2016-07-24 3 views
4

Рассмотрим следующий текст:Почему мое регулярное выражение делает это?

foo:·····¶ 
·bar x··¶ 
·lorem ipsum····¶ 
dolorsitamet···¶ 
···¶ 
consectetur adipiscing elit: 

Где средние точки указывают на пробелы и указывает символ новой строки.

Регулярное выражение (?:foo:\s*)(.+)(?:\n\s*) соответствует трех пробелам на пробельной линии, но регулярное выражение (?:foo:\s*)(.+)(?:\n\s+) соответствует и не включает в себя новую строку, следующую за dolorsitamet. Почему символ * не ведет себя жадно? Можно было бы ожидать, что третья группа (?:\n\s*) соответствовать

¶ 
···¶` 

Мой режим регулярных выражений является многострочным, dotall.

ответ

1

Жадная природа здесь не проблема. Проблемы, когда вы используете:

\n\s* 

И так .+ до этого жаден, \n\s* матчи самый последний \n во входном тексте т.е. (last-1)th линии (т.е. линии с 3 места) и останавливается.

RegEx Demo 1

Однако при использовании

\n\s+ 

Благодаря наличию квантора +, она требует по крайней мере один пробел после \n, следовательно, он не может соответствовать \n в (last-1)th линии (с последней строки в начале не имеет пробелов). Следовательно, он соответствует \n в строке, начинающейся с dolorsitamet, поскольку следующая строка имеет белые пробелы при запуске.

RegEx Demo 2

+0

Да, я использую Regex101 для изготовления регулярных выражений. То, что я на самом деле хочу, - это сопоставить все между 'foo: ···· ¶' и пробелами после' dolorsitamet ··· '(я не забочусь о завершающем пробеле, но не о новой строке), но он также должен верните то, что он сейчас делает для текста здесь https://regex101.com/r/jZ5hU0/1. Каким будет правильный способ его соответствия? –

+1

Nevermind, я нашел решение равным '(?: Foo: \ s *) (. +?) ((?: $) | (?: \ N \ + \ n))' –

+0

Немного упрощено: ' (?: Foo: \ S *) (\ п \ s + \ п | $) '(+.?) – anubhava

1

Он ведет себя жадно. Однако, чтобы соответствовать концу \n\s+, он должен соответствовать символу новой строки, за которым следует по крайней мере один символ пробела. В этом случае это следующая последняя строка новой строки, три пробела и последняя строка новой строки.

Если это не так, то .+ будет захватывать больше, но последняя часть не будет соответствовать, и двигатель регулярных выражений будет искать менее жадное решение, которое он находит.