RegEx: 20 passos curtos para dominar expressões regulares. Parte 1 Original aqui Na última parte dominamos as expressões regulares mais simples e já aprendemos alguma coisa. Nesta parte estudaremos projetos um pouco mais complexos, mas acredite, não será tão difícil quanto pode parecer. Então vamos continuar!
Etapa 8: estrela
Até agora, só conseguimos combinar strings de um determinado comprimento. Mas nos problemas mais recentes aproximámo-nos do limite do que podemos fazer com a notação que vimos até agora. Vamos supor, por exemplo, que não estamos limitados a identificadores Java de 3 caracteres, mas que podemos ter identificadores de qualquer comprimento. Uma solução que pode ter funcionado no exemplo anterior não funcionará no exemplo a seguir:
Etapa 9: ponto de interrogação "opcional"
Você já escreveu regex para resolver o último problema? Funcionou? Agora tente aplicá-lo aqui:
Etapa 10: sinal "ou"
Na etapa 8, tivemos alguma dificuldade em encontrar os diferentes tipos de números de ponto flutuante:
Etapa 8: estrela *
e sinal de mais+
Até agora, só conseguimos combinar strings de um determinado comprimento. Mas nos problemas mais recentes aproximámo-nos do limite do que podemos fazer com a notação que vimos até agora. Vamos supor, por exemplo, que não estamos limitados a identificadores Java de 3 caracteres, mas que podemos ter identificadores de qualquer comprimento. Uma solução que pode ter funcionado no exemplo anterior não funcionará no exemplo a seguir:
padrão: [a-zA-Z_$]\w\w string: __e $12 3 3,2 fo Bar r a23 mm ab x correspondências: ^^^ ^^^ ^^^ ^^^( Exemplo ) observaçãoque quando um identificador é válido, mas tem mais de 3 caracteres, apenas os três primeiros caracteres são correspondidos. E quando o identificador é válido, mas contém menos de 3 caracteres, então a regex não o encontra! O problema é que as expressões entre colchetes
[]
correspondem exatamente a um caractere, assim como classes de caracteres como \w
. Isso significa que qualquer correspondência na expressão regular acima deve ter exatamente três caracteres. Portanto, não funciona tão bem quanto esperávamos. *
Os caracteres especiais e podem ajudar aqui +
. Estes são modificadores que podem ser adicionados à direita de qualquer expressão para corresponder a essa expressão mais de uma vez. A Kleene Star (ou “asterisco”) *
indicará que o token anterior deve ser correspondido qualquer número de vezes, incluindo zero vezes. O sinal de mais +
indicará que você precisa pesquisar uma ou mais vezes. Assim, a expressão que precede +
é obrigatória (pelo menos uma vez), enquanto a expressão que precede *
é opcional, mas quando aparece, pode aparecer quantas vezes quiser. Agora, com esse conhecimento, podemos corrigir a expressão regular acima:
padrão: [a-zA-Z_$]\w* string: __e $123 3.2 fo Barr a23mm ab x corresponde: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^ ^( Exemplo ) Agora combinamos identificadores válidos de qualquer comprimento! Bingo! Mas o que aconteceria se usássemos ?
+
em vez de *
?
padrão: [a-zA-Z_$]\w+ string: __e $123 3,2 fo Barr a23mm ab x correspondências: ^^^ ^^^^ ^^ ^^^^ ^^^^^ ^^( Exemplo ) Perdemos a última partida
х
,. Isso ocorre porque requer +
que pelo menos um caractere seja correspondido, mas como a expressão entre parênteses []
anterior \w+
já 'comeu' o caractere x
, não há mais caracteres disponíveis, portanto a correspondência falha. Quando podemos usar +
? Quando precisamos encontrar pelo menos uma correspondência, mas não importa quantas vezes uma determinada expressão deva corresponder. Por exemplo, se quisermos encontrar quaisquer números que contenham uma vírgula decimal:
padrão: \d*\.\d+ string: 0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 correspondências: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^( Exemplo ) observaçãoque, ao tornar opcionais os números à esquerda da vírgula decimal, conseguimos encontrar 0,011 e 0,2. Para fazer isso, precisávamos combinar exatamente uma vírgula decimal
\.
e pelo menos um dígito à direita da vírgula com \d+
. A expressão regular acima não corresponderá a um número como 3.
, porque precisamos de pelo menos um dígito à direita da vírgula decimal para corresponder.
Como sempre, vamos resolver alguns problemas simples:
Encontre todas as palavras em inglês na passagem abaixo.padrão: string: 3 mais 3 é seis, mas 4 mais três é 7 correspondências: ^^^^ ^^ ^^^ ^^^ ^^^^ ^^^^^ ^^( Solução ) Encontre todos os símbolos de tamanho de arquivo na lista abaixo. Os tamanhos dos arquivos consistirão em um número (com ou sem ponto decimal) seguido por
KB
, MB
ou : GB
TB
padrão: string: 11TB 13 14,4MB 22HB 9,9GB TB 0KB corresponde: ^^^^ ^^^^^^ ^^^^^ ^^^( Solução )
Etapa 9: ponto de interrogação "opcional"?
Você já escreveu regex para resolver o último problema? Funcionou? Agora tente aplicá-lo aqui:
padrão: sequência: 1..3KB 5...GB ..6TB partidas:Obviamente, nenhuma dessas designações é um tamanho de arquivo válido; portanto, uma boa expressão regular não deve corresponder a nenhuma delas. A solução que escrevi para resolver o último problema corresponde a todos eles, pelo menos em parte:
padrão: \d+\.*\d*[KMGT]B string: 1..3KB 5...GB .. 6TB correspondências: ^^^^^^ ^^^^^^ ^^^( Exemplo ) Então qual é o problema? Na verdade, só precisamos de determinar uma vírgula, se houver. Mas
*
permite qualquer número de correspondências, incluindo zero. Existe uma maneira de combinar apenas zero vezes ou uma vez? Mas não mais de uma vez? Claro que sim. "opcional" ?
é um modificador que corresponde a zero ou a um dos caracteres anteriores, mas não mais:
padrão: \d+\.?\d*[KMGT]B string: 1.. 3KB 5...GB .. 6TB correspondências: ^^^ ^^^( Exemplo ) Estamos mais perto de uma solução aqui, mas não é bem isso que precisamos. Veremos como consertar isso em algumas etapas um pouco mais tarde.
Enquanto isso, vamos resolver este problema:
Em algumas linguagens de programação (por exemplo, Java), alguns números inteiros e de ponto flutuante (ponto) podem ser seguidos porl
/ L
e f
/ F
para indicar que devem ser tratados como long/float (respectivamente) em vez de int/double regulares. Encontre todos os números "longos" válidos na linha abaixo:
padrão: string: 13L longo 2l 19 L lL 0 correspondências: ^^^ ^^ ^^ ^( Solução )
Etapa 10: sinal "ou"|
Na etapa 8, tivemos alguma dificuldade em encontrar os diferentes tipos de números de ponto flutuante:
padrão: \d*\.\d+ string: 0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 correspondências: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^O padrão acima corresponde a números com vírgula decimal e pelo menos um dígito à direita da vírgula decimal. Mas e se também quisermos combinar strings como
0.
? (Nenhum número à direita da vírgula decimal.) Poderíamos escrever uma expressão regular como esta:
padrão: \d*\.\d* string: 0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 0. . correspondências: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^ ^( Exemplo ) Isto corresponde
0.
, mas também corresponde a um único ponto .
, como você pode ver acima. Na verdade, o que estamos tentando combinar são duas classes de strings diferentes:
- números com pelo menos um dígito à direita da vírgula
- números com pelo menos um dígito à esquerda da vírgula
padrão: \d*\.\d+ string: 0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 0. . correspondências: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^
padrão: \d+\.\d* string: 0,011 .2 42 2,0 3,33 4,000 5 6 7,89012 0. . correspondências: ^^^^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^Vemos que em nenhum desses casos as substrings
42
, 5
, 6
ou .
são encontradas pelo mecanismo. Para obter o resultado desejado, não nos faria mal combinar essas expressões regulares. Como podemos conseguir isso? O sinal "ou" |
nos permite especificar várias sequências possíveis de correspondências de uma só vez em uma expressão regular. Assim como []
o sinal "ou" nos permite especificar caracteres únicos alternativos, |
podemos especificar expressões alternativas com vários caracteres. Por exemplo, se quiséssemos encontrar “cachorro” ou “gato”, poderíamos escrever algo assim:
padrão: \w\w\w string: Obviamente , um cachorro é um animal de estimação melhor do que um gato . correspondências: ^^^^^^^^^ ^^^ ^^^^^^ ^^^ ^^^ ^^^( Exemplo ) ... mas corresponde a todas as sequências de caracteres triplos da classe "palavra". Mas “cachorro” e “gato” nem sequer têm letras em comum, então colchetes não nos ajudarão aqui. Aqui está a expressão regular mais simples que poderíamos usar que corresponde a ambas e apenas a estas duas palavras:
pattern: dog|cat string: Obviamente, um cachorro é um animal de estimação melhor que um gato . correspondências: ^^^ ^^^( Exemplo ) O mecanismo de expressão regular primeiro tenta corresponder a sequência inteira à esquerda do caractere
|
, mas se falhar, ele tenta corresponder a sequência à direita do caractere |
. Vários caracteres |
também podem ser encadeados para corresponder a mais de duas sequências alternativas:
padrão: dog|cat|pet string: Obviamente, um cachorro é um animal de estimação melhor do que um gato . correspondências: ^^^ ^^^ ^^^( Exemplo )
Agora vamos resolver mais alguns problemas para entender melhor esta etapa:
Use o sinal|
para corrigir a expressão regular decimal acima para produzir um resultado como este:
padrão: sequência: 0,011 ,2 42 2,0 3,33 4,000 5 6 7,89012 0. . correspondências: ^^^^^ ^^ ^^^ ^^^^ ^^^^^ ^^^^^^^ ^^( Solução ) Use sign
|
, classes de caracteres, "optional" ?
, etc. para criar uma única expressão regular que corresponda a números inteiros e de ponto flutuante (ponto), conforme discutido no problema no final da etapa anterior (este problema é um pouco mais complicado, sim ;))
padrão: string: 42L 12 x 3,4f 6l 3,3 0F LF .2F 0. correspondências: ^^^ ^^ ^^^^ ^^ ^^^ ^^ ^^^ ^^( Solução ) 20 passos curtos para dominar expressões regulares. Parte 3 RegEx: 20 passos curtos para dominar expressões regulares. Parte 4
GO TO FULL VERSION