我有一个包含许多对象文字的JavaScript文件:
// lots of irrelevant code
oneParticularFunction({
key1: "string value",
key2: 12345,
key3: "strings which may contain ({ arbitrary characters })"
});
// more irrelevant code
我需要编写一些Python代码来提取这些文字。
我的第一次尝试是正则表达式oneParticularFunction\(\{(.*?)\}\);
。但是如果文字包含"})"。
由于我知道对象在有效的JavaScript文件中是有效的JSON(匹配的引号,大括号等),有没有更优雅的方法来提取它们?
(换句话说,难以删除我不关心的所有其他JavaScript代码。)
编辑:最后,我对任何不包含子对象的对象使用正则表达式...
oneParticularFunction\((\{([^"}]*"[^"]*"[^"}]*)*?[^"]*?\})\);
...并用手跟踪打开/关闭括号,以便进行嵌套。
答案 0 :(得分:2)
为什么不写一个状态机来读取{并在每个{递增一个计数器并且每次递减它}所以当它再次达到0时,取中间的所有字符并使用python中的json解析器来检查它是否是有效与否?通过这种方式,你可以获得语法错误的好处,而不是简单的匹配与正则表达式的匹配(记住python是{免费所以误报是不可能的)。
答案 1 :(得分:2)
正则表达式代码:
(?<=(?:\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上测试了这段代码,似乎有效。您可以将其复制并粘贴到那里。如果它适用于其他对象文字,请告诉我。
答案 2 :(得分:1)
我能够使用它删除字符串中的所有括号,而不会消除或不匹配外部'({'和'})'
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)