Какие буквенные символы следует экранировать в регулярном выражении? - PullRequest
24 голосов
/ 30 марта 2011

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

[\w-.]

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

[\w\-.]

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

Ответы [ 5 ]

59 голосов
/ 30 марта 2011

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

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

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

Так что все это следует избегать. Есть несколько угловых случаев:

  • - не нуждается в побеге, если находится в самом начале или конце класса ([abc-] или [-abc]). В довольно многих реализациях регулярных выражений он также не нуждается в экранировании при размещении непосредственно после диапазона ([a-c-abc]) или класса сокращенных символов ([\w-abc]). Это то, что вы наблюдали
  • ^ не нужно убегать, когда не в начале класса: [^a] означает любой символ, кроме a, а [a^] соответствует либо a или ^, что равно: [\^a]
  • ] не нужно убегать, если это единственный символ в классе: []] соответствует символу ]
6 голосов
/ 30 марта 2011
[\w.-]
  • . обычно означает любой символ, но между [] нет особого значения
  • - между [] указывает диапазон, если только он не экранирован, либо первый или последний символ между []
4 голосов
/ 30 марта 2011

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

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

3 голосов
/ 30 марта 2011

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

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

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

0 голосов
/ 28 марта 2017

Если вы используете 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);
?>
...