我在发布之前查看了相关问题,但我无法修改任何相关的答案以使用我的方法(不擅长正则表达式)。
基本上,这是我现有的行:
$code = preg_replace_callback( '/"(.*?)"/', array( &$this, '_getPHPString' ), $code );
$code = preg_replace_callback( "#'(.*?)'#", array( &$this, '_getPHPString' ), $code );
它们都匹配''
和""
之间包含的字符串。我需要正则表达式来忽略它们之间包含的转义引号。因此,''
之间的数据将忽略\'
,""
之间的数据将忽略\"
。
非常感谢任何帮助。
答案 0 :(得分:68)
对于大多数字符串,您需要允许转义任何(不仅仅是转义引号)。例如您最有可能需要允许转义字符,例如"\n"
和"\t"
,当然还有转义转义:"\\"
。
这是一个经常被问到的问题,很久以前就已经解决了(并进行了优化)。 Jeffrey Friedl在他的经典着作中深入探讨了这个问题(作为一个例子):Mastering Regular Expressions (3rd Edition)。这是你正在寻找的正则表达式:
"([^"\\]|\\.)*"
版本1:正常工作但效率不高。
"([^"\\]++|\\.)*"
或"((?>[^"\\]+)|\\.)*"
版本2:如果您拥有所有权量词或原子组,则效率更高(参见:sin使用原子组方法的正确答案)。
"[^"\\]*(?:\\.[^"\\]*)*"
版本3:更高效。实现Friedl的:“展开循环”技术。不需要占有或原子组(即这可以在Javascript和其他功能较少的正则表达式引擎中使用。)
以下是双语和单引号子字符串的PHP语法推荐的正则表达式:
$re_dq = '/"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"/s';
$re_sq = "/'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'/s";
答案 1 :(得分:10)
试试这样的正则表达式:
'/"(\\\\[\\\\"]|[^\\\\"])*"/'
(简短)解释:
" # 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 `"`
以下代码段:
<?php
$text = 'abc "string \\\\ \\" literal" def';
preg_match_all('/"(\\\\[\\\\"]|[^\\\\"])*"/', $text, $matches);
echo $text . "\n";
print_r($matches);
?>
产生
abc "string \\ \" literal" def
Array
(
[0] => Array
(
[0] => "string \\ \" literal"
)
[1] => Array
(
[0] => l
)
)
正如您在Ideone上看到的那样。
答案 2 :(得分:1)
这有可能:
/"(?>(?:(?>[^"\\]+)|\\.)*)"/
/'(?>(?:(?>[^'\\]+)|\\.)*)'/
答案 3 :(得分:1)
这似乎与展开的循环一样快,基于一些粗略的基准,但更容易阅读和理解。它首先不需要任何回溯。
"[^"\\]*(\\.[^"\\]*)*"
答案 4 :(得分:0)
这会将引号留在
之外(?<=['"])(.*?)(?=["'])
并使用global
/ g将匹配所有群组
答案 5 :(得分:0)
根据 W3 资源: https://www.w3.org/TR/2010/REC-xpath20-20101214/#doc-xpath-StringLiteral
一般的正则表达式是:
"(\\.|[^"])*"
(+捕获组第一次检查时不需要加反斜杠)
说明:
"..."
引号之间的任何匹配(...)*
内部可以有从 0 到无穷大的任意长度\\.|[^"]
首先接受任何后面有斜杠的字符 | (或)然后接受任何不是引号的字符具有更好分组以便更好地处理任何引用的正则表达式的 PHP 版本可以是这样的:
<?php
$str='"First \\" \n Second" then \'This \\\' That\'';
echo $str."\n";
// "First \" \n Second" then 'This \' That'
$RX_inQuotes='/"((\\\\.|[^"])*)"/';
preg_match_all($RX_inQuotes,$str,$r,PREG_SET_ORDER);
echo $r[0][1]."\n";
// First \" \n Second
$RX_inAnyQuotes='/("((\\\\.|[^"])*)")|(\'((\\\\.|[^\'])*)\')/';
preg_match_all($RX_inAnyQuotes,$str,$r,PREG_SET_ORDER);
echo $r[0][2]." --- ".$r[1][5];
// First \" \n Second --- This \' That
?>
试试看:http://sandbox.onlinephpfunctions.com/code/4328cc4dfc09183f7f1209c08ca5349bef9eb5b4
重要提示:在这个时代,对于不确定的内容,您必须在正则表达式的末尾使用u
标志,例如/.../u
以避免破坏{{1 }} 字符串如 multi-byte
,或函数如 mb_ereg_match。