2010-06-27 4 views
3

Я пытаюсь написать регулярное выражение, чтобы распознать одну строку текста, с подчеркиванием (_), распознанным как символ продолжения строки. Например, «foo_ \ nbar» следует рассматривать как одну строку, потому что «foo» заканчивается символом подчеркивания. Я пытаюсь:Нарушает ли это самый «самый длинный» принцип?

$txt = "foo_\nbar"; 
print "$&\n" if $txt =~ /.*(_\n.*)*/; 

Однако, только эти отпечатки:

foo_ 

Это, кажется, нарушает "крайнее левое длинное" правило для регулярных выражений Perl!

Интересно, если я удалить последнюю звезду (*) в регулярном выражении, то есть:

$txt = "foo_\nbar"; 
print "$&\n" if $txt =~ /.*(_\n.*)/; 

это делает печати:

foo_ 
bar 

Но мне нужно звезду признать «0 или более "продолжений!

Что я делаю неправильно?

+0

Что вы пытаетесь достичь с помощью этого регулярного выражения? Что бы вы хотели с этим сделать? – Zaid

+0

"распознать одну строку текста, с символом подчеркивания (_), распознанным как символ продолжения строки" – JoelFan

ответ

6

Почему это происходит объясняется @ysth. Чтобы исправить это, вы можете использовать следующее регулярное выражение:

/([^_\n]|_.)*/s 
5

Perl не делает «самый левый самый длинный»; вместо этого каждая функция регулярного выражения имеет четко определенный способ действия. Ваш начальный * будет соответствовать столько раз, сколько возможно, если остальное регулярное выражение может совпадать. Для того, чтобы предотвратить его проглатывания _, сделать что-то вроде:

/(.*(?!(?<=_)\n)_\n)*.*/ 
+0

Вау ... это какая-то тяжелая магия регулярных выражений ... – JoelFan

+0

Не совсем: '. *' Соответствовать невооруженным строкам, '(?! ', но не заканчивайте на' '(? <= _)' что-то предшествующее символом '_',' \ n', которое является символом новой строки ') * * *, повторяющимся для максимально возможного количества строк. получите следующую строку – ysth

+0

ZyX's намного лучше, но менее литературный перевод определенной проблемы. – ysth

1

Есть два основных вкусов обычных конструкций экспрессии:

POSIX определяет крайний левый самый длинный вкус. Например: изменение «a | b» на «b | a» ничего не делает для полного соответствия.

PERL определяет левый смещенный вкус. Каждый «a | b» проверяет левую ветвь «a», и если это может совпадать, «b» никогда не проверяется. Таким образом, «a | b» редко совпадает с «b | a». Здесь a * подобен() | a | aa | aaa | aaaa | ...

+4

нет, a * подобен ... | aaaa | aaa | aa | a |(). а *? как() | a | aa | aaa | aaaa | .... – ysth

Смежные вопросы