Почему бы не создать обратную ссылку? - PullRequest
4 голосов
/ 14 марта 2011

Я понимаю, что, помещая ?: в начале круглых скобок регулярного выражения, вы не сможете создать обратную ссылку, которая должна быть быстрее.У меня вопрос, зачем это делать?Достаточно ли заметно увеличение скорости, чтобы оправдать это рассмотрение?При каких обстоятельствах это будет иметь такое большое значение, что вам нужно будет тщательно пропускать обратную ссылку каждый раз, когда вы не собираетесь ее использовать.Другим недостатком является то, что это затрудняет чтение, редактирование и обновление регулярного выражения (если в конечном итоге вы захотите использовать обратную ссылку позже).

Итак, в общем, зачем не создавать обратную ссылку?

Ответы [ 2 ]

13 голосов
/ 14 марта 2011

Я думаю, что вы путаете обратные ссылки, такие как \1 и группы захвата (...).

Обратные ссылки предотвращают все виды оптимизаций, делая язык нерегулярным.

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

http://www.regular -expressions.info / brackets.html поясняетзахват групп и обратные ссылки на них подробно.

РЕДАКТИРОВАТЬ:

При обратных ссылках, делающих регулярные выражения нерегулярными, рассмотрим следующее регулярное выражение, соответствующее комментариям lua:

/^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/

Итак, --[[...]] - это комментарий, --[=[...]=] - это комментарий, --[==[...]==] - это комментарий.Вы можете вкладывать комментарии, добавляя дополнительные знаки равенства в квадратных скобках.

Это не может быть сопоставлено строго обычным языком , поэтому простой конечный автомат не может обработать его в O (n)время - вам нужен счетчик.

Регулярные выражения Perl 5 могут справиться с этим с помощью обратных ссылок.Но как только вам требуется нерегулярное сопоставление с образцом, ваша библиотека регулярных выражений должна отказаться от простого подхода конечного автомата и использовать более сложный, менее эффективный код.

5 голосов
/ 14 марта 2011

Вы правы, производительность - не единственная причина избегать захвата групп - на самом деле это даже не самая важная причина.

Другим недостатком является то, что это затрудняет чтение, редактирование и обновление регулярного выражения (если в конечном итоге вы захотите использовать обратную ссылку позже).

Я смотрю на это с другой стороны: если вы обычно используете группы без захвата, легче отслеживать номера групп в тех случаях, когда вы делаете выбираете захватить что-то. В том же духе, если вы используете именованные группы (предполагая, что их регулярное выражение поддерживает их), вы должны всегда использовать именованные группы и всегда ссылаться на них (в обратных ссылках или замене) строки) по имени, а не по номеру. Последовательное соблюдение этих правил, по крайней мере, частично компенсирует штраф за удобочитаемость не захватывающих групп.

Да, PITA должна таким образом загромождать ваши регулярные выражения, и люди, которые пишут / поддерживают реализации регулярных выражений, знают это. В .NET вы можете установить опцию ExplicitCapture, при которой все «пустые» скобки будут обрабатываться как группы без захвата, а захватывать будут только именованные группы. В Perl 6 круглые скобки (с именами или без них) всегда фиксируются, а квадратные скобки используются для групп без захвата. Другие ароматы, вероятно, в конечном итоге последуют их примеру, но пока мы просто должны полагаться на хорошие привычки.

...