Я пытаюсь извлечь строки униграммы, би- и триграммы, которые образованы комбинацией некоторых из более мелких частей. Есть ли способ извлечь их по отдельности, не считая меньшие, когда они являются частью больших?
text = "the log user should able to identify log entries and domain log entries"
ngramList = ['log', 'log entries','domain log entries']
import re
counts = {}
for ngram in ngrams:
words = ngram.rsplit()
pattern = re.compile(r'%s' % "\s+".join(words),re.IGNORECASE)
counts[ngram] = len(pattern.findall(text))
print(counts)
текущий программный выход = 'log':3 ,'log entries':2,'domain log entries':1
ожидаемый результат = 'log' : 1 , 'log entries':1, 'domain log entries':1






Вы можете сначала отсортировать список ngram по размеру, а затем использовать re.subn для замены каждой ngram (от большого к маленькому) пустой строкой и одновременно подсчитать количество замен.
Поскольку вы сортируете ngram от большего к меньшему, вы гарантируете, что меньшие не будут считаться «частью больших», потому что вы удаляете их из строки в цикле.
import re
s = "the log user should able to identify log entries and domain log entries"
ngramList = ['log', 'log entries','domain log entries']
ngramList.sort(key=len, reverse=True)
counts = {}
for ngram in ngramList:
words = ngram.rsplit()
pattern = re.compile(r'%s' % "\s+".join(words), re.IGNORECASE)
s, n = re.subn(pattern, '', s)
counts[ngram] = n
print(counts)
Как указывает Виктор в комментариях, вы можете улучшить свой шаблон регулярного выражения. Теперь шаблон также будет соответствовать слову log в слове key logging. Конечно, вы хотите заключить токен в разрывы слов:
pattern = re.compile(r"\b(?:{})\b".format(r"\s+".join(ngram.split())), re.IGNORECASE)
Совершенно верно. Я добавил это как комментарий.
Кстати, OP, похоже, убежден, что r'%s' % "\s+"... необходим для создания необработанного строкового литерала. Это избыточно, и r'%s' % можно не использовать.
Это верно. Однако я считаю, что
pattern = re.compile(r"\b(?:{})\b".format(r"\s+".join(ngram.split())),re.IGNORECASE)будет лучше, поскольку он не учитываетlogвlogging.