Pelo que li online, é difícil entender o comportamento de uma correspondência não gananciosa (correspondência preguiçosa) em sed
. Estou intrigado com o que parece ser uma partida preguiçosa.
Em ~/tmp/tmp.txt
, tenho uma linha com 3 strings alfanuméricas separadas por 2 tabulações: TheQuick<TAB>BrownFox<TAB>JumpedOver
. Se eu emitir sed -n -E '/^.+\t.+\t.+$/p' ~/tmp/tmp.txt
, a linha será impressa.
Parece-me que não deveria porque, embora a expressão regular corresponda a 3 strings separadas por 2 tabulações, as strings não são alfanuméricas. Portanto, a primeira string deve engolir avidamente todos os caracteres da linha, não deixando nada para corresponder à primeira tabulação.
Como posso entender esse comportamento para criar expressões regulares confiáveis? Estou usando GNU sed
.
Um sistema de correspondência ganancioso significa apenas que ele tentará encontrar a maior string correspondente (ou seja, a primeira maior, ele irá parar de procurar na primeira correspondência para todo o regex), não que ele irá parar em uma string não correspondente, mesmo se as strings correspondentes existir. Pense nisso como a ordem de "encontre-me a maior correspondência possível, mas encontre-me uma correspondência!". Como permitir que o primeiro
.\+
coma toda a string significaria que o regex não corresponde, o mecanismo voltará e tentará outra coisa.No seu caso, é ainda mais simples, pois você está ancorando a regex no início e no final da linha (
^
e$
), para que.+
nunca chegue ao final da linha porque há outras coisas na expressão regular depois dela.Aqui está um exemplo que pode ajudar a explicar a correspondência gulosa:
Aqui, como a expressão regular
a*
significa "corresponde a 0 ou maisa
caracteres consecutivos", a correspondência gananciosa encontrará a maior string correspondente possível. Uma correspondência não gananciosa, usando PCRE, por exemplo, retornaria:Isso ocorre porque o non-greedy encontrará a string correspondente mais curta em vez da mais longa.
Não entendo por que você menciona alfanumérico ou como isso é relevante. Talvez você tenha entendido mal
.
e pense que só corresponde a strings alfanuméricas, mas não;.
irá corresponder a tudo (dependendo de qual tipo de expressões regulares você está usando e quais opções você dá, pode até combinar caracteres de nova linha). Se você deseja strings alfanuméricas, pode usar a classe de caracteres POSIX[[:alnum:]]
que corresponde a[a-zA-Z0-9]
.