2011-02-08 103 views
0

我以为php的perl兼容正则表达式(preg库)支持大括号作为分隔符。这应该是罚款:Php正则表达式与安全分隔符

{ello {world}i // should match on Hello {World 

大括号的主要观点是,只需要最左和右的,因此不需要转义内的。据我所知,PHP需要转义

{ello \{world}i // this actually matches on Hello {World 

这是预期的行为或PHP preg实施中的错误?

回答

1

当您在Perl中使用四个配对的ASCII括号类型中的任意一个模式分隔符时,只需在模式中转义未配对括号。这实际上是使用括号的全部目的。

Non-bracketing delimiters use the same character fore and aft, 
    but the four sorts of brackets (round, angle, square, curly) 
    will all nest, which means that 

     q{foo{bar}baz} 

    is the same as 

     'foo{bar}baz' 

    Note, however, that this does not always work for quoting Perl code: 

     $s = q{ if($a eq "}") ... }; # WRONG 

这就是为什么你经常看到有人在Perl代码中使用m{…}qr{…},尤其是对于使用多模式:这是在perlop中手册页“报价和报价般的运营商”,其内容部分下记录与/xᴀᴋᴀ(?x)。例如:

return qr{     
    (?=      # pure lookahead for conjunctive matching 
     \A     # always from start 
     . *?    # going only as far as we need to to find the pattern 
     (?: 
      ${case_flag} 
      ${left_boundary} 
      ${positive_pattern} 
      ${right_boundary} 
     ) 
    ) 
}sxm; 

请注意,这些嵌套大括号是没有问题的。

1

据我所知,期望的行为,否则编译器将如何允许组限制器?例如

[a-z]{1,5} 
+1

from http://perldoc.perl.org/perlre.html - “如果在任何其他上下文中出现花括号,则将其视为常规字符。” – binaryLV 2011-02-08 08:29:23

0

我发现,没有逃脱在这种情况下需要:

'ello {world'i 
(ello {world)i 

所以我的理论是,这个问题是与“{”只有分隔符。此外,下面的两个产生相同的误差:

{ello {world}i 
(ello (world)i 

使用开始/结束括号作为分隔符可能需要逃脱在表达式给定的大括号。

1

http://lv.php.net/manual/en/regexp.reference.delimiters.php

If the delimiter needs to be matched inside the pattern it must be escaped using a backslash. If the delimiter appears often inside the pattern, it is a good idea to choose another delimiter in order to increase readability.

所以这是预期的行为,不是一个错误。