【问题标题】:How to find JSON object in text with python如何使用python在文本中查找JSON对象
【发布时间】:2019-01-17 12:03:19
【问题描述】:

我正在尝试使用 python 正则表达式从文本中解析 JSON 对象。我找到了这个匹配:

'\{(?:[^{}]|(?R))*\}'

但是在 python 中我得到了这个错误:

re.error: unknown extension ?R at position 12

查看this regex101 example 中的正则表达式匹配。

【问题讨论】:

标签: python json regex


【解决方案1】:

您发现一个使用 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']}}

【讨论】:

  • 如果它有用,我 Frankenstein'ed extract_json_objects() 也提供了周围的文本,以便用户可以选择 json 美化对象以及包含它的字符串。 Adam can be found here.
【解决方案2】:

如果一行中只有一个JSON,可以使用索引方法查找第一个和最后一个括号来选择JSON:

firstValue = jsonString.index("{")
lastValue = len(jsonString) - jsonString[::-1].index("}")
jsonString = jsonStringEncoded[firstValue:lastValue]

【讨论】:

    【解决方案3】:

    这是因为 python re 模块很弱,不支持子程序和递归。改用 pypi regex 模块。它会编译你的正则表达式。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-31
      • 1970-01-01
      • 2014-05-13
      • 2019-07-03
      • 1970-01-01
      • 2022-11-11
      • 2020-03-27
      • 1970-01-01
      相关资源
      最近更新 更多