Próbuję dopasować dowolny zestaw znaków (w nawiasach kwadratowych) innych niż nawiasy kwadratowe ([^[]]+
) - chyba że ostatnia część ciągu znaków jest zgodna -notme
.
perl -sp -e "if (/[[^[]]+?(?!-notme)]$/../^no/)
{ print "#"; s/^yes/$VAR/; }" -- -VAR="CHANGED" /tmp/input
Mój plik wejściowy wygląda następująco:
-bash-4.2# cat /tmp/input
[test-ing]
yes
yes
no
maybe
[test-ing-notme]
yes
yes
no
maybe
Ale mój wynik wygląda następująco:
#[test-ing]
#CHANGED
#CHANGED
#no
maybe
#[test-ing-notme]
#CHANGED
#CHANGED
#no
maybe
Moje spekulacje są takie, że zestaw ujemny todopasowywanie do tego, co mój negatywny lookahead nie powinien pasować - stąd moja próba z leniwym dopasowaniem zbioru negatywnego, ale wynik jest taki sam, jakby był to chciwy mecz.
Oczekuję, że wynik będzie wyglądał następująco:
#[test-ing]
#CHANGED
#CHANGED
#no
maybe
[test-ing-notme]
yes
yes
no
maybe
Odpowiedzi:
2 dla odpowiedzi № 1Powinieneś zmienić wzór: /[[^[]]+?(?!-notme)]$/
do
/[[^]]++(?<!-notme)]$/
# ^ ^-------------- a negative loobehind before the closing bracket
# "---------------- a possessive quantifier to prevent backtracking
W ten sposób masz pewność, że „-notme” nie jest testowane na bezużytecznych pozycjach w łańcuchu.
Jak widać, nie można uciec zamykającemu nawiasowi w klasie postaci, jeśli ta znajduje się na pierwszej pozycji lub bezpośrednio po karetce negacji.