给出以下 json 字符串:
{"key":"val"ue","other":"invalid ""quo"te"}
我想捕获值中的每个非法双引号。在示例中,key 属性的值中有一个双引号,而名为 other 的属性中有三个双引号。
我看到多个评论指出这是无效的 json(正确)并且提供的 json 在接收之前应该是有效的。然而,这对我来说是不可能的。
假设这只会发生在值中而不是键中,我认为可以安全地假设起始序列是冒号后跟双引号。 结束序列将是双引号后跟逗号或右大括号。
我已经尝试了以下正则表达式(在许多其他版本中),这是最接近的,所以我想要的解决方案:
/:\s?".*?(").*?[,}]/i
这正确捕获了 key 属性中的一个双引号,但仅捕获了 'other' 属性中的第一个双引号。 我希望它捕获另外两个双引号以及单独的捕获。
我尝试过的另一个正则表达式:
/:\s?".*?("{1,})[^,}].*?[,}]/i
这与第一个正则表达式相同,但在一次捕获中捕获两个双引号(不推荐)
我的最终目标是分别捕获每个双引号,因此捕获四个。我认为为了实现这一目标,我需要一种使捕获组“贪婪”的方法?这样它就不会停在第一个双引号处。
我怎样才能实现这个目标?
我正在使用以下 PHP 代码来测试正则表达式:
$text = '{"key":"val"ue","other":"invalid ""quo"te"}';
$pattern = '/:\s?".*?(").*?[,}]/i';
preg_match_all($pattern, $text, $matches, PREG_OFFSET_CAPTURE);
echo '<pre>' . print_r($matches, true) . '</pre>';
我不会为此使用正则表达式。我只需手动扫描字符串:
function detectIllegals($text)
{
$illegals = [];
$indideString = false;
$len = strlen($text);
for($i=0;$i<$len;$i++)
{
$c = $text[$i];
if($c=='"')
{
if($indideString)
{
$c2 = $text[$i+1];
if($c2==':' || $c2==',' || $c2=='}')
$indideString = false;
else
$illegals[] = $i;
}
else
$indideString = true;
}
}
return $illegals;
}
$text = '{"key":"val"ue","other":"invalid ""quo"te"}';
$a = detectIllegals($text);
print_r($a);
输出:
Array
(
[0] => 11
[1] => 33
[2] => 34
[3] => 38
)