C #: Determinando se string é como este padrão; possível regex

votos
2

Considere uma cadeia que se parece com isso:

RR1 S5 C92

Este um endereço de rota rural para entrega fora da cidade-mail: Rota Rural, Site, Compartimento. Cada letra é seguida por um número e um espaço. Normalmente um a três dígitos, mas você nunca sabe quantos números poderia ser! Se o usuário é preguiçoso, eles podem ter entrado zero, um ou muitos espaços.

Pergunta: Qual regex você usaria para determinar se uma determinada string corresponde a este padrão?

Seu uso seria algo como isto:

string ruralPattern; //a regex pattern here
bool isRural = Regex.Match(someString, ruralPattern);

Update: Obrigado por suas sugestões! Desempenho e uso será dentro de um método estático em uma montagem a ser chamado de um serviço web. As cordas sendo verificado contra este padrão vai ser no máximo 50 caracteres. O método será chamado aproximadamente uma vez a cada 5 segundos. Todas as sugestões sobre mantendo-estática? Muito apreciado!

Publicado 26/08/2009 em 23:11
fonte usuário
Em outras línguas...                            


4 respostas

votos
9

Isso deve funcionar:

^[Rr][Rr]\d+ *[Ss]\d+ *[Cc]\d+$

ou como por outro comentário

^[Rr][Rr][0-9]+ *[Ss][0-9]+ *[Cc][0-9]+$

O que isso significa:

  • ^ - início de corda
  • [Rr] - próxima carvão animal deve ser um de R ou R
  • [Rr] - próxima carvão animal deve ser um de R ou R
  • \ D + ou [0-9] + - parte seguinte deve ser 1 ou mais dígitos
  • (Espaço) * - permitir a 0 ou mais espaços
  • [Ss] - próxima carvão animal deve ser um S ou s
  • \ D + ou [0-9] + - parte seguinte deve ser 1 ou mais dígitos
  • (Espaço) * - permitir a 0 ou mais espaços
  • [Cc] - próxima carvão animal deve ser um C ou c
  • \ D + ou [0-9] + - parte seguinte deve ser 1 ou mais dígitos
  • $ - final da string

Pode haver uma solução mais elegante, mas isso é muito fácil de ler.

Edit: Atualizado para incluir a entrada de alguns dos comentários

Respondeu 26/08/2009 em 23:12
fonte usuário

votos
3

E se...

someString = someString.Trim(); // eliminate leading/trailing whitespace
bool isRural = Regex.Match(
   someString,
   @"^rr\d+\s*s\d+\s*c\d+$",
   RegexOptions.IgnoreCase);

Isto elimina a comutação maiúsculas / minúsculas no interior do padrão e utiliza \spara permitir que qualquer (não nova linha) carácter em branco (por exemplo, separadores). Se você quiser espaços somente, em seguida, '\s'deve ser alterado para ' '.

Respondeu 27/08/2009 em 00:03
fonte usuário

votos
1

Vamos esclarecer os seguintes pressupostos:

  1. Há três seções para o string.
  2. seção 1 sempre começam com maiúsculas ou minúsculas RR e termina com um ou mais dígitos decimais.
  3. secção 2 sempre iniciar com maiúscula S ou minúsculas e termina com um ou mais dígitos decimais.
  4. secção 3 sempre iniciar com C superior ou inferior e termina com um ou mais dígitos decimais.

Para simplificar, o seguinte seria suficiente.

[Rr][Rr][0-9]+[ ]+[Ss][0-9]+[ ]+[Cc][0-9]+
  1. [Rr] significa exactamente um alfabeto R, caso superior ou inferior.
  2. [0-9] significa exatamente um dígito decimal.
  3. [0-9] + significa que pelo menos um, ou mais, dígitos decimais.
  4. [] + Significa que pelo menos um, ou mais, espaços.

No entanto, para ser útil, normalmente, quando você usa regex, também detectaria seções individuais para explorar a capacidade de correspondência para nos ajudar a atribuir valores de seção individuais para suas respectivas variáveis ​​/ individuais.

Por isso, a seguinte regex é mais útil.

([Rr][Rr][0-9]+)[ ]+([Ss][0-9]+)[ ]+([Cc][0-9]+)

Vamos aplicar esse regex para a cadeia

string inputstr = "Holy Cow RR12 S53 C21";

Isto é o que a sua correspondência regex iria deixá-lo saber:

start pos=9, end pos=21
Group(0) = Rr12 S53 C21
Group(1) = Rr12
Group(2) = S53
Group(3) = C21

Há três pares de colchetes elípticas / round. Cada par é uma seção da corda, que o compilador regex chama um grupo.

O compilador regex chamaria a partida de

  1. Toda combinava com a string como grupo 0
  2. rota rural como um grupo
  3. local no grupo 2 e
  4. compartimento, tal como o grupo 3.

Naturalmente, os grupos 1, 2 & 3 vai encontrar partidas, se e apenas se o grupo 0 tem um jogo.

Portanto, o algoritmo seria explorar isso com o seguinte pseudocódigo

string postalstr, rroute, site, compart;
if (match.group(0)!=null)
{
  int start = match.start(0);
  int end = match.end(0);
  postalstr = inputstr.substring(start, end);

  start = match.start(1);
  end = match.end(1);
  rroute = inputstr.substring(start, end);

  start = match.start(2);
  end = match.end(2);
  site = inputstr.substring(start, end);

  start = match.start(3);
  end = match.end(3);
  compart = inputstr.substring(start, end);
}

Além disso, você pode querer entrar em uma tabela de banco de dados com as colunas: rr, local, Compart, mas você só quer os numerais entrou sem a alfabetos "rr", "s" ou "c". Esta seria a regex com agrupamento aninhado de usar.

([Rr][Rr]([0-9]+))[ ]+([Ss]([0-9]+))[ ]+([Cc]([0-9]+))

E a correspondência vai deixar você saber o seguinte quando ocorrer uma correspondência para o grupo 0:

start=9, end=21
Group(0) = Rr12 S53 C21
Group(1) = Rr12
Group(2) = 12
Group(3) = S53
Group(4) = 53
Group(5) = C21
Group(6) = 21
Respondeu 27/08/2009 em 01:54
fonte usuário

votos
0

FYI: Se você estiver indo para estar usando este RegEx para testar um monte de dados, a sua melhor aposta seria dizer .NET pré-compilar-lo - serão compilados em IL e conceder um aumento de desempenho, ao invés de simplesmente interpretar a RegEx padrão de cada vez. Especifique-o como um membro estático em qualquer classe contém o método, assim:

private static Regex re = new Regex("pattern", RegexOptions.Compiled | RegexOptions.IgnoreCase);

... e o método para testar se uma string corresponde ao padrão é ...

bool matchesString = re.IsMatch("string");

Boa sorte.

Respondeu 27/08/2009 em 03:08
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more