PHP:正则表达式忽略引号内的转义引号

Bri*_*ham 28 php regex

我在发布之前查看了相关问题,但我无法修改任何相关的答案以使用我的方法(不擅长正则表达式).

基本上,这是我现有的行:

$code = preg_replace_callback( '/"(.*?)"/', array( &$this, '_getPHPString' ), $code );

$code = preg_replace_callback( "#'(.*?)'#", array( &$this, '_getPHPString' ), $code );
Run Code Online (Sandbox Code Playgroud)

它们都匹配''和之间包含的字符串"".我需要正则表达式来忽略它们之间包含的转义引号.所以之间的数据''会忽略,\'而之间的数据""会被忽略\".

任何帮助将不胜感激.

rid*_*ner 71

对于大多数字符串,您需要允许转义任何内容(不仅仅是转义引号).例如,你很可能需要允许转义字符像"\n""\t"当然,转义逃逸:"\\".

这是一个经常被问到的问题,很久以前就已经解决了(并进行了优化).Jeffrey Friedl在他的经典着作中深入探讨了这个问题(作为一个例子):掌握正则表达式(第3版).这是你正在寻找的正则表达式:

好:

"([^"\\]|\\.)*"
版本1:正常工作但效率不高.

更好:

"([^"\\]++|\\.)*""((?>[^"\\]+)|\\.)*"
版本2:如果您拥有所有权量词或原子组,则效率更高(请参阅:sin使用原子组方法的正确答案).

最好:

"[^"\\]*(?:\\.[^"\\]*)*"
版本3:更高效.实现Friedl的:"展开循环"技术.不需要占有或原子组(即这可以在Javascript和其他功能较少的正则表达式引擎中使用.)

以下是双语和单引号子字符串的PHP语法推荐正则表达式:

$re_dq = '/"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"/s';
$re_sq = "/'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'/s";
Run Code Online (Sandbox Code Playgroud)

  • +1 对于这个 `"[^"\\]*(?:\\.[^"\\]*)*"` 比 `"(\\.|[^"\\]+ 更好地避免交替和替补)*"` (2认同)
  • 很好的答案. (2认同)

Bar*_*ers 10

试试像这样的正则表达式:

'/"(\\\\[\\\\"]|[^\\\\"])*"/'
Run Code Online (Sandbox Code Playgroud)

(简短)解释:

"                 # match a `"`
(                 # open group 1
  \\\\[\\\\"]     #   match either `\\` or `\"`
  |               #   OR
  [^\\\\"]        #   match any char other than `\` and `"`
)*                # close group 1, and repeat it zero or more times
"                 # match a `"`
Run Code Online (Sandbox Code Playgroud)

以下片段:

<?php
$text = 'abc "string \\\\ \\" literal" def';
preg_match_all('/"(\\\\[\\\\"]|[^\\\\"])*"/', $text, $matches);
echo $text . "\n";
print_r($matches);
?>
Run Code Online (Sandbox Code Playgroud)

生产:

abc "string \\ \" literal" def
Array
(
    [0] => Array
        (
            [0] => "string \\ \" literal"
        )

    [1] => Array
        (
            [0] => l
        )

)
Run Code Online (Sandbox Code Playgroud)

正如你在Ideone上看到的那样.