Подтвердить что ты не робот

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

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

[\w-.]

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

[\w\-.]

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

[\w.-]
  • . обычно означает любой символ, но между [] не имеет особого значения
  • - между [] указывает диапазон, если только он не экранировался или не был первым или последним символом между []

Ответ 4

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

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

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

Ответ 5

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