正则表达式 | PHP 捕获 json 字符串中的每个非法双引号

问题描述 投票:0回答:1

给出以下 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>';
php json regex preg-match-all pcre2
1个回答
0
投票

我不会为此使用正则表达式。我只需手动扫描字符串:

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
)
© www.soinside.com 2019 - 2024. All rights reserved.