Как найти объект JSON в тексте с помощью Python

Вы должны сделать distinct вызов на курсоре , возвращенном из find, а не в коллекции:

tags = db.mycoll.find({"category": "movie"}).distinct("tags")

-2
задан Martijn Pieters 17 January 2019 в 12:17
поделиться

2 ответа

Это потому, что модуль python re довольно слаб и не поддерживает подпрограммы и рекурсию Вместо этого попробуйте модуль pypi regex. Это скомпилирует ваше регулярное выражение.

0
ответ дан Predicate 17 January 2019 в 12:17
поделиться

Вы нашли регулярное выражение, использующее синтаксис, который модуль стандартной библиотеки Python re не поддерживает.

Когда вы посмотрите на ссылку regex101, вы увидите, что шаблон работает при использовании библиотеки PRCE , а проблемный синтаксис (?R), который выдает ошибку, использует функцию под названием [ 1114] рекурсии . Эта функция поддерживается только подмножеством механизмов регулярных выражений .

Вы можете установить библиотеку regex , альтернативный механизм регулярных выражений для Pythont, который явно поддерживает этот синтаксис:

>>> 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() ; см. Как использовать модуль 'json' для чтения по одному объекту JSON за раз? для примера подхода. В то время как рекурсивное регулярное выражение может найти JSON- подобный тексту , подход декодера позволит вам извлечь только действительный текст 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']}}
0
ответ дан Martijn Pieters 17 January 2019 в 12:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: