Термин может быть: < /p>
Слово, например. 'Apple' < /li>
Фраза, например. 'Cherry Pie' < /li>
логическое и слов и фраз, например. 'Сладкий пирог и пикантный пирог и безе' < /li>
< /ul>
Соответствие - это то, где слово или фраза существует вокруг границ слов, так: < /p>
Код: Выделить всё
match(term='apple', string='An apple a day.') # True
match(term='berry pie', string='A delicious berry pie.') # True
match(term='berry pie', string='A delicious blueberry pie.') # False
< /code>
У меня в настоящее время около 40 терминов, большинство из них - простые слова. Количество терминов со временем увеличится, но я бы не ожидал, что они выйдут за пределы 400. />
Скорость-это наиболее важные критерии, и я хотел бы использовать существующий код тех, кто умнее меня, а не пытаться реализовать белую бумагу. :) < /p>
Пока самое быстрое решение, которое я придумал: < /p>
def data():
return [
"The apple is the pomaceous fruit of the apple tree, species Malus domestica in the rose family (Rosaceae).",
"This resulted in early armies adopting the style of hunter-foraging.",
"Beef pie fillings are popular in Australia. Chicken pie fillings are too."
]
def boolean_and(terms):
return '(%s)' % (''.join(['(?=.*\\b%s\\b)' % (term) for term in terms]))
def run():
words_and_phrases = ['apple', 'cherry pie']
booleans = [boolean_and(terms) for terms in [['sweet pie', 'savoury pie', 'meringue'], ['chicken pie', 'beef pie']]]
regex = re.compile(r'(?i)(\b(%s)\b|%s)' % ('|'.join(words_and_phrases), '|'.join(booleans)))
matched_data = list()
for d in data():
if regex.search(d):
matched_data.append(d)
< /code>
regex вводится как: < /p>
(?i)(\b(apple|cherry pie)\b|((?=.*\bsweet pie\b)(?=.*\bsavoury pie\b)(?=.*\bmeringue\b))|((?=.*\bchicken pie\b)(?=.*\bbeef pie\b)))
Timeit results:
print timeit.Timer('run()', 'from __main__ import run').timeit(number=10000)
1.41534304619
< /code>
Без ликаников (т.е. логический и логический) это действительно быстро, но как только они добавляют, скорость значительно замедляется. < /p>
У кого -нибудь есть идеи о том, как это можно улучшить? Есть ли способ оптимизировать Lookahead, или, может быть, совершенно другой подход? Я не думаю, что Stemming сработает, так как он имеет тенденцию быть немного жадным с тем, что соответствует.
Подробнее здесь: https://stackoverflow.com/questions/542 ... s-in-a-lis