Aprender Expressões Regulares

votos
166

Eu realmente não entendo expressões regulares. Pode explicar-lhes que me de uma forma fácil de seguir? Se houver quaisquer ferramentas online ou livros, você também pode ligar para eles?

Publicado 07/08/2008 em 15:05
fonte usuário
Em outras línguas...                            


1 respostas

votos
679

A parte mais importante é os conceitos. Depois de entender como os blocos de construção trabalho, diferenças na quantidade sintaxe para pouco mais de dialetos leves. A camada em cima da sintaxe do seu mecanismo de expressão regular é a sintaxe da linguagem de programação que você está usando. Linguagens como Perl remover a maior parte desta complicação, mas você tem que manter em mente outras considerações se você estiver usando expressões regulares em um programa C.

Se você pensar em expressões regulares como blocos de construção que você pode misturar e combinar como quiser, ele ajuda você a aprender a escrever e depurar seus próprios padrões, mas também como entender padrões escritos por outros.

Comece simples

Conceitualmente, os mais simples expressões regulares são caracteres literais. O padrão Ncorresponde ao caráter 'N'.

As expressões regulares ao lado do outro seqüências jogo. Por exemplo, o padrão Nickcorresponde a sequência de 'N' seguida por 'i' seguido de 'c' seguido de 'k'.

Se você já usou grepem Unix, mesmo que seja apenas para procurar cadeias-você aparência comum já usando expressões regulares! (A reem greprefere-se a expressões regulares.)

Encomendar a partir do menu

Adicionando um pouco de complexidade, você pode combinar tanto 'Nick' ou 'nick' com o padrão [Nn]ick. A parte entre colchetes é uma classe de caracteres , o que significa que corresponde exatamente um dos personagens fechados. Você também pode usar faixas em classes de personagens, por isso [a-c]corresponde quer 'a' ou 'b' ou 'c'.

O padrão .é especial: e não apenas combinando um ponto literal, ele corresponde qualquer caractere . É o mesmo conceitualmente como a classe de personagem realmente grande [-.?+%$A-Za-z0-9...].

Pense em classes de personagens como menus: escolher apenas um.

atalhos votos

Usando .pode salvar você lotes de digitação, e há outros atalhos para padrões comuns. Digamos que você quer combinar inteiros não negativos: uma maneira de escrever que é [0-9]+. Dígitos são um alvo jogo freqüente, assim que você poderia passar a usar \d+para combinar inteiros não negativos. Outros são \s(espaços em branco) e \w(caracteres de palavra: alfanuméricos ou sublinhado).

As variantes uppercased são os seus complementos, por isso \Scorresponde a qualquer non caráter -whitespace, por exemplo.

Uma vez que não é suficiente

De lá, você pode repetir partes do seu padrão com quantificadores . Por exemplo, o padrão ab?ccorresponde 'abc' ou 'AC' porque o ?quantificador faz o subpadrão ele modifica opcional. Outros quantificadores são

  • * (Zero ou mais vezes)
  • + (Uma ou mais vezes)
  • {n}(exatamente n vezes)
  • {n,}(pelo menos n vezes)
  • {n,m}(pelo menos, n não há mais do que os tempos mas m vezes)

Colocando alguns destes blocos em conjunto, o padrão [Nn]*ickcorresponde a todos de

  • ick
  • usuario
  • usuario
  • Nnick
  • nNick
  • nnick
  • (e assim por diante)

O primeiro jogo demonstra uma lição importante: *sempre tem sucesso! Qualquer padrão pode corresponder a zero vezes.

Agrupamento

Um quantificador modifica o padrão à sua esquerda imediata. Você pode esperar 0abc+0para corresponder '0abc0', '0abcabc0', e assim por diante, mas o padrão imediatamente à esquerda do mais quantificador é c. Isto significa 0abc+0partidas '0abc0', '0abcc0', '0abccc0', e assim por diante.

Para corresponder a uma ou mais sequências de 'abc' com zeros nas extremidades, usar 0(abc)+0. Os parênteses indicam um sub-padrão que pode ser quantificada como uma unidade. Também é comum para motores de expressão regular para salvar ou "capturar" a parte do texto de entrada que corresponda a um grupo entre parênteses. Pedaços extrair desta forma é muito mais flexível e menos do que contar índices e propenso a erros substr.

alternação

Anteriormente, vimos uma maneira de corresponder quer 'Nick' ou 'nick'. Outra é com alternância como em Nick|nick. Lembre-se que a alternância inclui tudo à sua esquerda e tudo à sua direita. Use agrupamento parênteses para limitar o escopo de |, por exemplo , (Nick|nick).

Para outro exemplo, você poderia equivalentemente escrever [a-c]como a|b|c, mas isso é provável que seja abaixo do ideal porque muitas implementações assumir alternativas terão comprimentos superiores a 1.

escapando

Embora alguns personagens corresponder-se, outros têm significados especiais. O padrão \d+não corresponde barra invertida seguida por D minúscula seguido por um sinal de mais: para conseguir isso, usaríamos \\d\+. Uma barra invertida remove o significado especial do caractere seguinte.

cobiça

quantificadores de expressões regulares são gananciosos. Isso significa que eles coincidir com a quantidade de texto que pode possivelmente permitindo que todo o padrão para coincidir com sucesso.

Por exemplo, digamos que a entrada é

"Olá," ela disse, "Como você está?"

Você pode esperar ".+"para corresponder apenas 'Olá', e, em seguida, ser surpreendido quando você vê que combinava de 'Olá' todo o caminho 'você?'.

Para alternar do ganancioso do que se poderia pensar como cauteloso, adicionar um extra ?para o quantificador. Agora você entender como \((.+?)\), a exemplo da sua pergunta funciona. Ele corresponde à sequência de uma esquerda-parêntese literal, seguido por um ou mais caracteres, e terminado por um parênteses-direita.

Se a sua entrada é '(123) (456)', então a primeira captura será '123'. quantificadores não-gananciosos querem permitir que o resto do padrão para começar a correspondência mais rapidamente possível.

(Quanto à sua confusão, eu não sei de qualquer dialeto de expressão regular, onde ((.+?))faria a mesma coisa. Eu suspeito que algo se perdeu na transmissão em algum lugar ao longo do caminho.)

âncoras

Use o padrão especial ^para corresponder apenas no início de sua entrada e $para corresponder apenas no final. Fazendo "bookends" com os seus padrões onde você diz: "Eu sei o que está na frente e para trás, mas me dar tudo entre" é uma técnica útil.

Digamos que você quer combinar comentários de forma

-- This is a comment --

você escreveria ^--\s+(.+)\s+--$.

Construa o seu próprio

As expressões regulares são recursiva, então agora que você compreende estas regras básicas, você pode combiná-los como quiser.

Ferramentas para a escrita e depuração de expressões regulares:

livros

recursos livres

Nota de rodapé

†: A declaração acima que .corresponde a qualquer caractere é uma simplificação para fins pedagógicos que não é rigorosamente verdade. Dot corresponde a qualquer caractere, exceto nova linha, "\n"mas, na prática você raramente esperar um padrão como .+para atravessar uma fronteira nova linha. Expressões regulares Perl ter um /sinterruptor e Java Pattern.DOTALL, por exemplo, para fazer .corresponder a qualquer caractere em tudo. Para idiomas que não possuem esse recurso, você pode usar algo como [\s\S]para corresponder "qualquer espaço em branco ou qualquer não-espaço em branco", em outras palavras, qualquer coisa.

Respondeu 03/05/2010 em 17:09
fonte usuário

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