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

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

 [\w-.] 

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

 [\w\-.] 

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

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

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

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

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

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

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

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

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

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

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

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