带引号的带引号的字符串由另一个引号转义(两个双引号)

时间:2014-04-28 21:37:31

标签: php regex double-quotes

所以引用字符串的正则表达式已经反复解决。这里有一个很好的答案:https://stackoverflow.com/a/5696141/692331

$re_dq = '/"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"/s';

似乎是PHP的标准解决方案。

我的问题是我的报价被另一个报价转义。例如:

="123 4556 789 ""Product B v.24"""

="00 00 F0 FF ""Licence key for blah blah"" hfd.34"

=""

以前的字符串应分别与以下字符串匹配:

string '123 4556 789 ""Product B v.24""' (length=31) 

string '00 00 F0 FF ""Licence key for blah blah"" hfd.34' (length=48) 

string '' (length=0) 

给出的例子只是说明字符串可能是什么样子,而不是我将匹配的实际字符串,数字可以达到数万。

我需要一个与双引号字符串匹配的正则表达式模式,该字符串可能或不包含两个双引号的序列。

更新5/5/14:

See Answer Below

2 个答案:

答案 0 :(得分:1)

修改:根据您的请求,使用少量mod来记录空引号。

(?<!")"(?:[^"]|"")*"

原始解决方案:

(?<!")"(?:[^"]|"")+"

演示:

<?php
$string = '
"123 4556 789 ""Product B v.24"""
"00 00 F0 FF ""Licence key for blah blah"" hfd.34"';
$regex='~(?<!")"(?:[^"]|"")+"~';
$count = preg_match_all($regex,$string,$m);
echo $count."<br /><pre>";
print_r($m[0]);
echo "</pre>";
?>

输出:

2

Array
(
    [0] => "123 4556 789 ""Product B v.24"""
    [1] => "00 00 F0 FF ""Licence key for blah blah"" hfd.34"
)

答案 1 :(得分:1)

我发现了来自zx81

的模式
$re_dq_answer = '/="(?:[^"]|"")*"/'

导致每个匹配的字符后回溯。我发现我可以调整我问题最顶层的模式以满足我的需要。

$re_dq_orignal = '/="[^"\\\\]*(?:\\\\.[^"\\\\]*)*"/s';

变为

$re_dq_modified = '/="([^"]*(?:""[^"]*)*)"/';

's'模式修饰符不是必需的,因为模式不使用\ s元字符。

我必须匹配的最长字符串是28,000个字符,这导致Apache在堆栈溢出时崩溃。我不得不将堆栈大小增加到32MB(linux default is 8mb, windows is 1mb)只是为了得到!我不希望每个线程都有这么大的堆栈大小,所以我开始寻找更好的解决方案。

示例(在Regex101上测试):一个字符串(长度= 3,200),需要6,637个步骤才能使用$ re_dq_answer进行匹配,现在需要使用$ re_dq_modified进行141步骤。我会说略有改进!