2011-02-06 3 views
4

Я столкнулся с статьей PHP о регулярных выражениях, которые использовали (. *?) в своем синтаксисе. Насколько я могу видеть, он ведет себя так же, как (. *)Регулярное выражение. *? vs. *

Есть ли какие-либо преимущества использования (. *?)? Я не могу понять, почему кто-то это использовал.

+3

Они ведут себя по-разному. – BoltClock

+2

Кто бы это сказал, «в программировании иногда возникает проблема. Затем вы используете регулярное выражение для решения этой проблемы. Теперь у вас есть 2 проблемы».? – makdad

+1

@phooze: Каждый. –

ответ

7

.* жадный, .*? нет. Однако это имеет смысл только в контексте. Учитывая закономерность:

<br/>(.*?)<br/> и <br/>(.*)<br/>, а вход <br/>test<br/>test2<br/>,

.* будет соответствовать <br/>test<br/>test2<br/>,

.*? будет соответствовать только <br/>test<br/>.

Примечание: никогда не используйте регулярное выражение для анализа сложного html.

+0

Спасибо! этот ответ был мне очень ясен! – Tiddo

+0

+1 для приятного примера, но (http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454) – SingleNegationElimination

+0

добавил примечание. Я забыл об этом. – Femaref

8

в большинстве вкусов регулярного выражения, *? производство - это не жадный повтор. Это означает, что производство .*? сначала совпадает с пустой строкой, а затем, если это не удается, один символ и так далее, пока совпадение не завершится успешно. Напротив, жадное производство .* сначала пытается сопоставить весь ввод, а затем, если это не удается, он пытается уменьшить один символ.

Эта концепция применима только к механизмам регулярного выражения, которые используют рекурсивный обратный поиск для соответствия неоднозначным выражениям. Теоретически они соответствуют точно таким же откликам, но, поскольку они сначала пробуют разные вещи, вероятно, что они будут намного быстрее, чем другие.

Это также может быть полезно, когда группы захвата (в рекурсивных и NAV-типах одинаково) используются для извлечения информации из соответствующего действия. Например, выражение, подобное

"(.*?)" 

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

+0

так обычно, если вы используете его как часть регулярного выражения (. *?), Будет быстрее, чем (. *)? – Tiddo

+0

@ Тиддо: Это не может быть обобщено. В любом случае может произойти откат для некоторого ввода. – SingleNegationElimination

+0

Чтобы уточнить, '*' или '*?' Следует выбирать на основе правильной интерпретации ввода, а не производительности. Если производительность является проблемой, рассмотрите возможность использования чего-то иного, кроме рекурсивного механизма регулярного выражения обратного отслеживания. – SingleNegationElimination