2011-02-08 2 views
0

Я думал, что регулярное выражение, совместимое с perl-совместимым php (preg library), поддерживает фигурные скобки как разделители. Это должно быть прекрасно:PHP-регулярное выражение с безопасными разделителями

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

Главное фигурных скобок является то, что он принимает только самые левые и правые из них, таким образом, не требуя никакой возможности избежать для внутренних. Насколько я знаю, PHP требует спасаясь

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

Является ли это ожидаемое поведение или ошибка в реализации PHP препрега?

ответ

1

Если в Perl вы используете для разделителя шаблонов любой из четырех парных типов кронштейнов ASCII, вам нужно только избежать непарные скобки внутри шаблона. Это действительно целая цель использования скобок. Это отражено в perlop страницы руководства под «Quote и Цитирование типа операторов», в котором говорится, в частности:

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 

Вот почему вы часто видите люди используют m{…} или qr{…} в коде Perl, особенно для многопоточных паттернов, используемых с /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

из http://perldoc.perl.org/perlre.html - «Если фигурная скобка встречается в любом другом контексте, она рассматривается как обычный символ». – binaryLV

+0

Очень похоже, что сейчас. Если учитывать только первый и последний скобки. Поскольку php не должен формировать поиск и замену в одной строке, а, скорее, как два разных аргумента одной функции, не должно быть проблем, оставляя все в неэкранированном. –

+0

@binaryLV: Хотя я не был полностью исчерпывающим в своем ответе, я просто ускользал от «этого ожидаемого поведения». Спасибо за ссылку, хотя. –

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.

Так это ожидаемое поведение, а не ошибка.

Смежные вопросы