JavaRush /Blogue Java /Random-PT /RegEx: 20 passos curtos para dominar expressões regulares...
Artur
Nível 40
Tallinn

RegEx: 20 passos curtos para dominar expressões regulares. Parte 2

Publicado no grupo Random-PT
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. RegEx: 20 passos curtos para dominar expressões regulares.  Parte 2 - 1Então vamos continuar!

Etapa 8: estrela *e sinal de mais+

RegEx: 20 passos curtos para dominar expressões regulares.  Parte 2 - 2Até 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, MBou : GBTB
padrão:
string:   11TB 13 14,4MB 22HB 9,9GB TB 0KB 
corresponde: ^^^^ ^^^^^^ ^^^^^ ^^^  
( Solução )

Etapa 9: ponto de interrogação "opcional"?

RegEx: 20 passos curtos para dominar expressões regulares.  Parte 2 - 3Você 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 por l/ Le f/ Fpara 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"|

RegEx: 20 passos curtos para dominar expressões regulares.  Parte 2 - 4Na 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:
  1. números com pelo menos um dígito à direita da vírgula
  2. números com pelo menos um dígito à esquerda da vírgula
Vamos escrever as 2 expressões regulares a seguir, independentes uma da outra:
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, 6ou .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
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION