您发现一个使用 Python 标准库 re 模块不支持的语法的正则表达式。
当您查看 regex101 链接时,您会发现该模式在使用 PRCE library 时有效,而引发错误的有问题的 (?R) 语法使用了一个名为 recursion 的功能。只有subset of regex engines 支持该功能。
您可以安装 regex library,它是 Python 的替代正则表达式引擎,它明确支持该语法:
>>> import regex
>>> pattern = regex.compile(r'\{(?:[^{}]|(?R))*\}')
>>> pattern.findall('''\
... This is a funny text about stuff,
... look at this product {"action":"product","options":{...}}.
... More Text is to come and another JSON string
... {"action":"review","options":{...}}
... ''')
['{"action":"product","options":{...}}', '{"action":"review","options":{...}}']
另一种选择是尝试使用JSONDecoder.raw_decode() method 解码以{ 开头的任何部分;有关示例方法,请参阅How do I use the 'json' module to read in one JSON object at a time?。虽然递归正则表达式可以找到 JSON-like 文本,但解码器方法只能让您提取 有效 JSON 文本。
这是一个执行此操作的生成器函数:
from json import JSONDecoder
def extract_json_objects(text, decoder=JSONDecoder()):
"""Find JSON objects in text, and yield the decoded JSON data
Does not attempt to look for JSON arrays, text, or other JSON types outside
of a parent JSON object.
"""
pos = 0
while True:
match = text.find('{', pos)
if match == -1:
break
try:
result, index = decoder.raw_decode(text[match:])
yield result
pos = match + index
except ValueError:
pos = match + 1
演示:
>>> demo_text = """\
This is a funny text about stuff,
look at this product {"action":"product","options":{"foo": "bar"}}.
More Text is to come and another JSON string, neatly delimited by "{" and "}" characters:
{"action":"review","options":{"spam": ["ham", "vikings", "eggs", "spam"]}}
"""
>>> for result in extract_json_objects(demo_text):
... print(result)
...
{'action': 'product', 'options': {'foo': 'bar'}}
{'action': 'review', 'options': {'spam': ['ham', 'vikings', 'eggs', 'spam']}}