/ / Crie o regex mais curto possível - regex

Crie o regex mais curto possível - regex

Eu quero criar um regex que corresponda a qualquer um desses valores

7-5

6-6 ((0-99) - (0-99))

6-4

6-3

6-2

6-1

6-0

0-6

1-6

2-6

3-6

4-6

o exemplo de 6-6 é um caso especial, aqui estão alguns exemplos de valores:

6-6 (23-8)

6-6 (4-25)

6-6 (56-34)

É possível fazer um regex que possa fazer isso?

Em caso afirmativo, é possível estender ainda mais esse regex para o caso especial de 6 a 6, de forma que a diferença entre os dois números dentro dos parênteses seja igual a 2 ou -2?

Eu poderia facilmente escrever isso com código procedural, mas estou realmente curioso para saber se alguém pode criar um regex para isso.

Por último, se poderia ser mais alargado de tal forma queos dígitos individuais estavam em seus próprios grupos de correspondência que eu ficaria espantado. Um exemplo seria para 7-5, eu poderia ter um grupo de correspondência que só tinha o valor 7 e outro que tinha o valor 5. No entanto, para 6-6 (24-26) Eu gostaria de um grupo de jogos que tivesse os seis primeiros, um grupo de correspondências para os segundos 6, um grupo de correspondências para os 24 e um grupo de jogos para os 26.

Isso pode ser impossível, mas alguns de vocês provavelmente conseguem essa parte do caminho até lá.

Boa sorte e obrigado pela ajuda.

Respostas:

1 para resposta № 1

NÃO. A resposta é "Nós podemos", e a razão é porque você está tentando usar um martelo para cavar um buraco.

O problema com a escrita de um longo "inteligente" (esteA palavra causa uma reação instintiva em muitas pessoas que são muito mais anti-regex do que eu). O regex é que, daqui a seis meses, você terá esquecido aqueles recursos inteligentes de regex que você usou tão fortemente, e você terá escrito seis meses de código relacionado a outra coisa, e você voltará ao seu impressionante regex e terá que ajustar um detalhe, e você dirá, "WTF?"

Isso é o que (eu entendo) você quer, em Perl:

# data is in $_
if(/7-5|6-[0-4]|[0-4]-6|6-6 ((d{1,2})-(d{1,2}))/) {
if($1 and $2 and abs($1 - $2) == 2) {
# we have the right difference
}
}

Alguns podem dizer que o regex dado é um pouco demais, mas eu não acho que seja tão ruim. Se o d{1,2} bit é um pouco obscuro você poderia usar dd? (que é o que eu usei no início, mas não gostei da repetição).


1 para resposta № 2

Você pode fazer assim:

7-5|6-[0-4]|[0-5]-6|6-6 (dd?-dd?)

Basta adicionar parêntesis para obter seus grupos de jogos.


0 para resposta № 3

Fora do topo da minha cabeça (pode haver alguns erros, mas o princípio deve ser bom):

d-d | 6-6 (d + -d +)

E como em qualquer regexp, você pode colocar o que deseja extrair entre parênteses para grupos de correspondências:

(d) - (d) | (6) - (6) ((d) + - (d +))

No caso de 6 a 6, os dois primeiros parênteses devem obter os seis e os dois segundos devem receber os valores de vários dígitos que vêm depois.


0 para a resposta № 4

Aqui está um que irá corresponder apenas aos números desejados e permitir que você obtenha cada dígito pelo nome:

p = r"(?P<a>[0-4]|6|7)-(?P<b>[0-4]|6|5) *(((?P<c>d{1,2})-(?P<d>d{1,2})))?"

Para obter cada dígito, você pode usar:

values = re.search(p, string).group("a", "b", "c", "d")

Que irá retornar uma tupla de quatro elementos com os valores que você está procurando (ou None se nenhuma correspondência foi encontrada).


Um problema com esse padrão é que ele corrigirá as coisas entre parênteses, independentemente de haver correspondência entre "6-6". Este só irá coincidir com o parêntese final se 6-6 for correspondido:

p = r"(?P<a>[0-4]|(?P<tmp_a>6)|7)-(?P<b>(?(tmp_a)(?P<tmp_b>6)|([0-4]|5)))(?(tmp_b) *(((?P<c>d{1,2})-(?P<d>d{1,2})))?)"


Eu não sei de qualquer maneira de procurar uma diferença entre os números entre parênteses; regex só sabe sobre seqüências de caracteres, não valores numéricos.



(Estou assumindo a sintaxe do python aqui; a sintaxe do perl é um pouco diferente, embora o perl ofereça suporte ao modo python de fazer as coisas.)