Какие буквенные символы следует экранировать в регулярном выражении?


Я только что написал регулярное выражение для использования с функцией php preg_match, которое содержит следующую часть:

[\w-.]

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

[\w\-.]

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

Author: Pelle ten Cate, 2011-03-30

5 answers

Во многих реализациях регулярных выражений применяются следующие правила:

Метасимволы внутри класса символов:

  • ^ (отрицание)
  • - (диапазон)
  • ] (конец занятия)
  • \ (символ побега)

Так что все это должно быть спасено. Однако есть несколько угловых случаев:

  • - не нуждается в экранировании, если он помещен в самом начале или в конце класса ([abc-] или [-abc]). В довольно большом количестве регулярных выражений реализации, он также не нуждается в экранировании при размещении непосредственно после диапазона ([a-c-abc]) или класса символов короткой руки ([\w-abc]). Это то, что вы наблюдали
  • ^ не нуждается в экранировании, когда это не в начале класса: [^a] означает любой символ, кроме a, а [a^] соответствует либо a, либо ^, что равно: [\^a]
  • ] не нуждается в экранировании, если это единственный символ в классе: []] соответствует символу ]
 56
Author: Bart Kiers, 2011-03-30 08:58:28
[\w.-]
  • . обычно означает любой символ, но между [] не имеет особого значения
  • - между [] указывает диапазон, если только он не экранирован, или первый или последний символ между []
 6
Author: bw_üezi, 2011-03-30 09:09:28

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

Вместо того, чтобы избегать его, вы могли бы поместить его в конце урока, [\w.-]

 4
Author: Your Common Sense, 2011-03-30 09:00:01

Полная остановка теряет свое мета-значение в классе символов.

- имеет особое значение в классе символов. Если он не помещен в начале или в конце квадратных скобок, его необходимо экранировать. В противном случае он обозначает диапазон символов (A-Z).

Однако вы вызвали другой особый случай . [\w-.] работает, потому что \w не обозначает ни одного символа. Как таковой PCRE не может создать диапазон символов. \w является возможным некогерентный класс символов, поэтому нет конечного символа, который можно было бы использовать для создания диапазона Z till .. Также полная остановка . будет предшествовать первому символу ascii a, который \w может совпадать. Нет никакого диапазона, который можно было бы построить. С тех пор - работал, не убегая для вас.

 3
Author: mario, 2011-03-30 09:06:05

Если вы используете php и вам нужно избежать специальных символов регулярного выражения, просто используйте preg_quote:

Пример из php.net:

<?php
// In this example, preg_quote($word) is used to keep the
// asterisks from having special meaning to the regular
// expression.

$textbody = "This book is *very* difficult to find.";
$word = "*very*";
$textbody = preg_replace ("/" . preg_quote($word, '/') . "/",
                          "<i>" . $word . "</i>",
                          $textbody);
?>
 0
Author: Soaku, 2017-03-28 16:35:51