Почему ключевые слова не анализируются первыми и не включаются при сопоставлении свободного текста? - PullRequest
0 голосов
/ 14 декабря 2018

Мне показалось, что я понял логику pyparsing, но не могу понять, почему не работает нижний пример.

Я пытаюсь разобрать комментарии в открытом тексте, где продукт или набор продуктов могут быть упомянуты либо в началеили конец комментария.Названия продуктов также могут быть опущены в комментарии.

На выходе должен быть список упомянутых продуктов и описание к ним.

Ниже приведены несколько тестов.Анализ разбирает все как «описание», а не сначала подбирает продукты (разве это не то, что должен делать негатив?)

Что не так в моем понимании?

import pyparsing as pp

products_list = ['aaa', 'bbb', 'ccc']
products = pp.OneOrMore(' '.join(products_list))

word = ~products + pp.Word(pp.alphas)
description = pp.OneOrMore(word)

comment_expr = (pp.Optional(products("product1")) + description("description") + pp.Optional(products("product2")))

matches = comment_expr.scanString("""\
                                aaa is a good product
                                I prefer aaa
                                No comment
                                aaa bbb are both good products""")

for match in matches:
    print match

Ожидаемые результаты будут:

product1: aaa, description: is a good product
product2: aaa, description: I prefer
description: No comment
product1: [aaa, bbb] description: are both good products

1 Ответ

0 голосов
/ 15 декабря 2018

Сокращенная эквивалентность Pyparsing между строками и литералами предназначена для удобства, но иногда это приводит к неожиданным и нежелательным обстоятельствам.В этих строках:

products_list = ['aaa', 'bbb', 'ccc']
products = pp.OneOrMore(' '.join(products_list))

.Я уверен, что вы хотели, чтобы товар соответствовал любому продукту.Но вместо этого OneOrMore передается в качестве аргумента:

' '.join(products_list)

Это чисто строковое выражение, в результате чего string"aaa bbb ccc".Передавая OneOrMore, вы говорите, что products - это один или несколько экземпляров строки «aaa bbb ccc».

Чтобы получить прогноз, вам нужно изменить продукты на:

products = pp.oneOf(products_list)

или даже лучше:

products = pp.MatchFirst(pp.Keyword(p) for p in products_list)

Тогда ваш негативный взгляд будет работать лучше.

...