给定以下json字符串:{"key":"val"ue","other":"invalid ""quo"te"}
我想捕获值中的每个非法双引号。在示例中,key属性的值中有一个双引号,而other属性中有三个双引号。
我看到很多评论指出这是无效的json(正确),提供的json在接收之前应该是有效的。然而,这在我的情况下是不可能的。
假设这只会发生在值中而不是键中,我认为可以安全地假设起始序列是冒号后跟双引号。结尾序列是一个双引号,后面跟着逗号或右大括号。
我已经尝试了下面的正则表达式(在许多其他版本中),这是最接近的,所以我想要的解决方案:/:\s?".*?(").*?[,}]/i
这正确地捕获了key属性中的一个双引号,但只捕获了“other”属性中的第一个双引号。我想它捕捉其他两个双引号以及一个单独的捕捉。
我试过的另一个正则表达式:/:\s?".*?("{1,})[^,}].*?[,}]/i
这与第一个正则表达式相同,但在一次捕获中捕获两个双引号(不可取)
我的最终目标是分别捕获每个双引号,因此需要四次捕获。我想我需要的是一种让捕获组“贪婪”的方法来完成这一任务?这样它就不会在第一个双引号处停止。
我如何才能做到这一点?
我使用以下PHP代码来测试Regex:
$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>';
2条答案
按热度按时间puruo6ea1#
你能做的就是用一个变种的诡计...
诀窍是我们匹配我们不想要的在交替的 * 左侧 *(
|
),然后我们捕获我们想要的在 * 右侧 *。PCRE的好处是,左侧只有skip可用。
See this demo at regex101
在
(*SKIP)(*F)
的左边,所有“正确”的引号get matched (regex101)和 skipped 都在交替之前。任何剩余的引号都在右侧|"
单独 * 匹配 *。最后,您可以使用
PREG_OFFSET_CAPTURE
来获取每个“非法引用”的位置。oo7oh9g92#
我不会使用regex来做这件事。我会手动扫描字符串:
输出量: