RegEx: menor correspondência possível ou correspondência não rápida

98

Como faço para dizer ao RegEx (versão .NET) para obter a menor correspondência válida em vez da maior?

Jonathan Allen
fonte

Respostas:

192

Para uma expressão regular como .*ou .+, acrescente um ponto de interrogação ( .*?ou .+?) para corresponder ao mínimo de caracteres possível. Para corresponder opcionalmente a uma seção, (?:blah)?mas sem corresponder, a menos que seja absolutamente necessário, use algo como (?:blah){0,1}?. Para uma correspondência repetida (usando {n,}ou {n,m}sintaxe), anexe um ponto de interrogação para tentar corresponder o mínimo possível (por exemplo, {3,}?ou {5,7}?).

A documentação sobre quantificadores de expressão regular também pode ser útil.

DMI
fonte
7
Não sei se sou o único com esse mal-entendido, mas é importante observar: embora seja verdade que o operador não ganancioso corresponderá ao mínimo de caracteres possível, ainda pode não ser a correspondência que alguém está procurando para. "O mínimo de caracteres possível" não é igual a "correspondência mais curta possível" em relação aos padrões RegEx. Veja a resposta abaixo do meu comentário: Com abcabke a.+?k, RegEx corresponderá a toda a string.
finefoot
Linha2 "mas sem correspondência, a menos que seja absolutamente necessário": o que isso significa?
Chovendo em
70

O operador não ganancioso ?,. Igual a:

.*?
David Hedlund
fonte
45

O operador não ganancioso não significa a correspondência mais curta possível:

abcabk

a.+?k corresponderá a toda a string (neste exemplo) em vez de apenas os três últimos sinais.

Eu gostaria de realmente encontrar a menor correspondência possível.

Essa é a última correspondência possível para ' a' ainda permitir todas as correspondências para k.

Acho que a única maneira de fazer isso é usar uma expressão como:

a[^a]+?k

Jonathan
fonte
2
Ou pesquise na ordem inversa, começando no final, quando as correspondências estiverem aninhadas: "(ab (abk) bk)".
LBogaardt
7
@LBogaardt como alguém pesquisaria na ordem inversa? não entendi
azerafati
2
@LBogaardt Pergunta ainda aberta: como alguém faria uma busca na ordem inversa? Digamos que eu queira pegar cab. Se minha entrada for caaacabe eu procurar por a.*?bela, ela retornará a string inteira em vez da correspondência curta interna. Como eu pesquisaria para trás a partir do b?
C4d
3
Inverta a string e, em seguida, aplique o regex.
Jonathan Allen
3
Isso é muito útil. Para pessoas como eu tentando entender o que está acontecendo aqui, a forma genérica é START[^START]*?END(onde START e END são suas regexs de caractere inicial e final). Significa essencialmente "combinar qualquer coisa de INÍCIO a FIM, onde os caracteres intermediários não incluem INICIAR novamente"
derekantrican