Regex \ R在字符类中不起作用

时间:2015-05-07 13:51:13

标签: php regex

在PHP中,与任何换行序列匹配的转义字符\R在字符类中不起作用。

我最近在stackoverflow上的另一个答案中了解了这个特殊字符,说实话我还没有找到很多在线记录它的存在 - 除了在用户评论中,它在php.net上没有提到。 / p>

问题(S):

  • 为什么\R不能在角色类中工作?
  • 哪里有记录?

示例1:https://regex101.com/r/vA8xV3/3

$a = "line1
      line2"

echo preg_replace('/\R/',' ',$a);

返回(查找匹配,替换为单个空格):

line1 line2

示例2:https://regex101.com/r/vA8xV3/2

$a = "line1
      line2"

echo preg_replace('/[\R]/',' ',$a);

返回(不匹配):

line1
line2

4 个答案:

答案 0 :(得分:5)

来自PCRE manual

  

转义字符类中的序列

     

可以使用定义单个字符值的所有序列   内部和外部字符类。另外,里面一个   characterclass,\b被解释为退格符(十六进制08)。

     字符类中不允许

\N \B\R\X不是   特殊的字符类。像其他未被认识的逃脱   序列,它们被视为文字字符“B”,“R”,   默认情况下为“X” ,但如果设置了PCRE_EXTRA选项则会导致错误。   在外部特征类中,这些序列具有不同的含义。

(强调我添加的相关位)

答案 1 :(得分:3)

这是正确的行为。 \ R仅适用于外部字符类。 (至少在grep和其他许多人中也是如此)

对于grep:

https://stat.ethz.ch/R-manual/R-devel/library/base/html/regex.html

PHP使用类似perl的表达式,请参阅peardoc:

http://perldoc.perl.org/perlrebackslash.html#Misc

  

由于\ R可以匹配多个字符的序列,因此不能   放入一个括号内的角色类; / [\ R] /是一个错误;使用\ v   代替

答案 2 :(得分:1)

至于字符类中不允许\R的原因,在字符类中允许\d\s\w,...,因为\R可以匹配CR LF序列(\r\n),它由2个代码点组成。出于同样的原因,在字符类中不允许使用\X,因为它匹配一个字形集群,它可以包含多个代码点。

字符类应该只匹配单个代码点/代码单元,这使得它成为一个确定性构造,因为它不需要回溯。允许字符类匹配代码点/代码单元序列会导致字符类具有可变长度,使得最小长度/最大长度分析复杂化,这在多个优化中使用。它还需要修改匹配的语义。例如,给定[\r\n\R],它是否应与字符串\r\n中的"\r\n"匹配,还是应该遵循声明的顺序并仅匹配\r?如果失败,我们应该允许它回溯吗?

我不确定PCRE的实施情况。但是,在Java中,长度分析用于优化重复构造(例如,重复固定长度构造,您不必存储每次重复中匹配的字符数量以进行回溯),优化输入字符串不会的情况满足最小长度要求,并确定是否允许使用后视中的表达式。

答案 3 :(得分:0)

认为我理解你的问题, 基本上,一个字符类会明确地匹配[]之间的内容,因此在您的情况下,[\R]将匹配\R。 例如,在字符串balhblahRajndsf\中,您将与\ and R匹配。这有意义吗?

http://www.zytrax.com/tech/web/regex.htm

请参阅以上链接中的括号,范围和否定