使用正则表达式匹配JSON

Matching JSON with a regular expression

本文关键字:JSON 正则表达式      更新时间:2023-09-26

我有一个包含许多对象字量的JavaScript文件:

// lots of irrelevant code
oneParticularFunction({
    key1: "string value",
    key2: 12345,
    key3: "strings which may contain ({ arbitrary characters })"
});
// more irrelevant code

我需要写一些Python代码来提取这些文字。

我的第一个尝试是正则表达式oneParticularFunction'('{(.*?)'}');。但如果字面量包含"})",则此操作失败。

因为我知道对象将是有效的JSON(匹配引号,大括号等)在一个有效的JavaScript文件,有没有一个更优雅的方式来提取它们?

(换句话说,困难在于删除所有我不关心的其他JavaScript代码。)

编辑:最后,我对任何不包含子对象的对象使用正则表达式…

oneParticularFunction'(('{([^"}]*"[^"]*"[^"}]*)*?[^"]*?'})');

…并手动跟踪任何有嵌套的开/闭大括号。

为什么不写一个状态机来读取{并在每个{上增加计数器并在每个}上减少它,所以当它再次达到0时,取中间的所有字符并使用python的json解析器来检查它是否有效?这样,您就可以从语法错误中获益,而不是简单地从正则表达式中匹配不匹配(请记住python是{自由的,因此不可能出现误报)。

正则表达式代码:

(?<=(?:'s'"))['s'S]+?(?='")|(?<=(?:'s))'d+

在https://regex101.com/r/bfNkvF/3

的正则表达式的实例

在Python中使用前面的正则表达式:

import re
text = '''oneParticularFunction({
key1: "string value",
key2: 12345,
key3: "strings which may contain ({ arbitrary characters })"
});'''
for m in re.finditer(r"(?<=(:'s'"))['s'S]+?(?='")|(?<=(:'s))'d+", text):
    print('%s' % (m.group(0)))
我在pythontutor上测试了这段代码,它似乎可以工作。你可以复制粘贴到这里。让我知道它是否适用于其他对象字面量

我能够使用这个从字符串中删除所有括号而不消除或不匹配外部'({'和'})'

while True:
    newstring = re.sub(r'('('{.*)'{([^{}]*)'}(.*'}'))', r''1'2'3', mystring)
    if newstring == mystring:
        break
    mystring = newstring

这里有3组(我知道,这很难区分)。第一个是('('{.*)。它会找到你的({然后再找到最里面的{

我们知道它是最里面的{,因为第二组([^{}]*)。这将匹配任何非{}的内容。

然后,(.*'}'))查找最里面的}之后的所有内容。

整个匹配被这三个组组合在一起取代({}被忽略)。它重复这个过程,直到没有匹配的大括号可以替换。

如果您也想替换()的,您可以将其修改为

newstring = re.sub(r'('('{.*)('{|'()([^{}()]*)('}|'))(.*'}'))', r''1'3'5', mystring)