Python регулярное выражение для подсчета нескольких совпадающих строк в предложениях - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь получить количество шаблонов, сгенерированных из строки hello awesome world, найденной в большом тексте.Шаблоны создаются путем перестановки слов и замены одного слова на * между ними.В этом примере я использую только 4 шаблона, чтобы упростить вещи.Я не очень знаком с регулярными выражениями, поэтому мой код пока не соответствует всем, что мне нужно.Я, наверное, скоро это выясню, но я не уверен, что это будет хорошо масштабироваться, когда я буду кормить реальными данными.

Вопрос в том, как мне исправить мой код и существуют ли лучшие / более быстрые способы достижения моей цели?Вот мой код с пояснениями.

import re
from collections import Counter


# Input text. Could consist of hundreds of thousands of sentences.
txt = """
Lorèm ipsum WORLD dolor AWESOME sit amèt, consectetur adipiscing elit. 
Duis id AWESOME HELLO lorem metus. Pràesent molestie malesuada finibus. 
Morbi non èx a WORLD HELLO AWESOME erat bibendum rhoncus. Quisque sit 
ametnibh cursus, tempor mi et, sodàles neque. Nunc dapibus vitae ligula at porta. 
Quisque sit amet màgna eù sem sagittis dignissim et non leo. 
Quisque WORLD, AWESOME dapibus et vèlit tristique tristique. Sed 
efficitur dui tincidunt, aliquet lèo eget, pellentesque felis. Donec 
venenatis elit ac aliquet varius. Vestibulum ante ipsum primis in faucibus
orci luctus et ultrices posuere cubilia Curae. Vestibulum sed ligula 
gravida, commodo neque at, mattis urna. Duis nisl neque, sollicitudin nec 
mauris sit amet, euismod semper massa. Curabitur sodales ultrices nibh, 
ut ultrices ante maximus sed. Donec rutrum libero in turpis gravida 
dignissim. Suspendisse potenti. Praesent eu tempor quam, id dictum felis. 
Nullam aliquam molestie tortor, at iaculis metus volutpat et. In dolor 
lacus, AWESOME sip HELLO volutpat ac convallis non, pulvinar eu massa.
"""

txt = txt.lower()

# Patterns generated from a 1-8 word input string. Could also consist of hundreds of 
# thousands of patterns
patterns = [
    'world',
    'awesome',
    'awesome hello', 
    'world hello awesome',
    'world (.*?) awesome'   # '*' - represents any word between
]

regex = '|'.join(patterns)
result = re.findall(regex, txt)
counter = Counter(result)
print(counter)
# >>> Counter({'awesome': 5, 'world': 3})

# For some reason i can't get strings with more than one word to match

# Expected output
found_pattern_counts = {
    'world': 3,
    'awesome': 5,
    'awesome hello': 1, 
    'world hello awesome': 1,
    'world * awesome': 2
}

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Вы не использовали подстановочный знак правильно, я исправил его, и теперь он работает так, как вы описали, и теперь вы можете создать дополнительную функцию для этой операции:

patterns = [
    'world',
    'awesome',
    'awesome hello', 
    'world hello awesome',
    'world (.*?) awesome'
]


result = {} 
for pattern in patterns:
   rex = re.compile(fr'{pattern}') 
   count = len(rex.findall(txt))   
   result[pattern] = result.get(pattern, 0) + count

print(result)
0 голосов
/ 02 февраля 2019

Вы можете заглянуть в

re.finditer()

Итераторы сэкономят вам много ресурсов, если вам не нужны все данные сразу (что вам вряд ли когда-либо понадобится).Таким образом, вам не нужно хранить столько информации в памяти.Посмотрите на это Сохраняют ли итераторы память в Python?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...