Точка в RegEx опасна - PullRequest
2 голосов
/ 20 ноября 2008

У меня сложилось впечатление, что Точка '.' Персонаж (подстановочный знак) опасен для использования. Мой страх необоснован? Спасибо

Ответы [ 8 ]

12 голосов
/ 20 ноября 2008

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

8 голосов
/ 20 ноября 2008

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

Из regex tutorial

Точка соответствует одному символу, безразлично, что это за символ. Единственным исключением являются символы новой строки.

В большинстве разновидностей регулярных выражений точка не будет соответствовать символу новой строки по умолчанию. Таким образом, по умолчанию точка является короткой для класса отрицательных символов [^ \ n] (разновидности регулярных выражений UNIX) или [^ \ r \ n] (разновидности регулярных выражений Windows).

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

8 голосов
/ 20 ноября 2008

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

6 голосов
/ 21 ноября 2008

VonC превзошел меня, указывая на мою статью . Раздел «экономно используйте точку» отвечает на ваш вопрос.

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

5 голосов
/ 20 ноября 2008

Я бы не сказал «опасно», по крайней мере, вообще. Тем не менее:

  • . * Следует избегать там, где это возможно, потому что это может убить производительность вашего регулярного выражения при большом количестве возвратов, так как он пытается найти лучшее совпадение, и, если токен, который следует после него, появляется более одного раза на входе, вы, вероятно, не получите тот матч, который хотели, потому что он ищет максимально длинный матч. . *? помогает с проблемой возврата и устраняет проблему «слишком длинного соответствия», но не использует. на всех имеет тенденцию быть более эффективным.

  • Потому что. может соответствовать чему угодно (кроме, как правило, конца строки), это может соответствовать чему-то, чего вы не ожидали / не ожидали. В контексте безопасности это может быть опасно.

3 голосов
/ 20 ноября 2008

Не забывайте, что вы часто можете использовать [^x]* вместо .*?x. Последний может потреблять x, если необходимо завершить сопоставление, но первый не может. . более вероятно, будет опасно, если вашему регулярному выражению разрешено сопоставлять многострочные строки, с. возможность представлять новую строку. Как бы то ни было, вас действительно должно беспокоить только то, что вы используете .* или .*?, хотя во многих случаях вы этого захотите. .{0,10} и тому подобное менее склонны к тому, что ваше регулярное выражение начинает работать абсурдно медленно.

2 голосов
/ 20 ноября 2008

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

Как и во многих других инструментах, легко застрять на среднем уровне регулярного выражения и никогда по-настоящему не освоить их. Мне кажется, это хороший способ перетащить себя через этот горб. Обратите внимание, что я не говорю, что вы никогда не должны использовать точку снова. просто дайте ему отдохнуть несколько месяцев, пока вы узнаете, что еще могут предложить регулярные выражения.

0 голосов
/ 20 ноября 2008

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

.*<one>.*<two>.*<three>.*</three>.*</two>.*</one>.*

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...