应该在正则表达式中转义哪些字面字符?

时间:2011-03-30 08:50:43

标签: php regex escaping pcre

我刚刚编写了一个用于php函数preg_match的正则表达式,其中包含以下部分:

[\w-.]

匹配任何单词字符,以及减号和点。虽然它似乎在preg_match中工作,但我试图将它放入一个名为Reggy的实用程序中并且它抱怨“char class中的空范围”。试验和错误告诉我这个问题是通过转义减号,将正则表达式转换为

来解决的
[\w\-.]

由于原版似乎在PHP中工作,我想知道为什么我应该或不应该转义减号,并且 - 因为点也是一个在PHP中有意义的字符 - 为什么我不需要逃避点。我使用的实用程序是愚蠢的,它是否与另一个正则表达式方言一起使用或者我的正则表达式是否真的不正确而且我很幸运preg_match让我逃脱它?

5 个答案:

答案 0 :(得分:59)

在许多正则表达式实现中,以下规则适用:

字符类中的元字符是:

  • ^(否定)
  • -(范围)
  • ](课程结束)
  • \(逃脱字符)

所以这些都应该被转义。但是有一些极端情况:

  • -如果放在课程的开头或结尾([abc-][-abc]),则无需转义。在相当多的正则表达式实现中,当直接放在范围([a-c-abc])或简写字符类([\w-abc])之后,它也不需要转义。这是你观察到的
  • ^在课程开始时时无需转义:[^a]表示除a[a^]之外的任何字符匹配a^,等于:[\^a]
  • ]如果它是班级中唯一的字符,则不需要转义:[]]匹配字符]

答案 1 :(得分:6)

[\w.-]
  • .通常表示任何字符,但[]之间没有特殊含义
  • {li> -之间的[]表示范围,除非它已被转义或[]之间的第一个或最后一个字符

答案 2 :(得分:4)

虽然确实存在some characters should be escaped in a regex,但你不是要求正则表达式而是关于字符类。短划线符号是特殊的。

而不是转义它,你可以把它放在课程结束时[\w.-]

答案 3 :(得分:3)

句号在字符类中失去了它的元含义。

-在字符类中有特殊含义。如果它没有放在方括号的开头或末尾,则必须将其转义。否则它表示字符范围(A-Z)。

然而,您触发了另一个特例[\w-.]有效,因为\w不表示单个字符。因此,PCRE不可能创建字符范围。 \w可能是非连贯的符号类,因此没有可用于创建范围Z till .的结束符。此外,句号.将位于a可匹配的第一个ascii字符\w之前。没有范围可构建。因此,-无需逃避就可以工作。

答案 4 :(得分:0)

如果您使用的是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);
?>