Регулярное выражение Python для всех пар слов - PullRequest
1 голос
/ 28 сентября 2019

Мне нужно составить список каждой пары слов последовательно в строке с регулярным выражением, соответствующая часть кода такова:

for word in re.findall(r'\w+\b.*?\w+', text):

Теперь давайте возьмем в качестве примера текст «Это случайный текст» , то, что я хочу, это список вроде этого:

['Это', 'это', 'случайный »,« случайный текст »]

Вместо этого я получаю следующее:

['Это', 'arandom ']

Как это исправить?Заранее спасибо.

Ответы [ 5 ]

2 голосов
/ 28 сентября 2019

Вы сказали, что слова разделены случайным количеством пробелов и / или знаков препинания, для этого я использовал [\s\.]+.

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

import re

text ="""This. is a random text"""

pattern = re.compile(r'(\w+[\s\.]+)(?=(\w+))')
for match in pattern.finditer(text):
    # rebuild the word
    element = ''.join(match.groups())
    print(element)

Ouput:

This. is
is a
a random
random text

Обратите внимание, что по умолчанию положительный прогноз не является группой захвата, поэтому я сделал это (?=(\w+)), чтобы захватить слово внутри него.Первая группа - (\w+[\s\.]+).и я использовал join для повторного построения конкатенации групп.

1 голос
/ 28 сентября 2019

Если вы хотите использовать regex для этой задачи, взгляните на это:

(\w+)\s+(?=(\w+))

Regex Demo

Хитрость заключается в использовании положительный прогноз для второго слова и захватить его в группе.Чтобы вывести результирующие пары, объедините результаты совпадений групп 1 и 2.

0 голосов
/ 28 сентября 2019

вам не нужно использовать регулярные выражения, в этом случае вы можете просто использовать split

st = "This is a random text"
sp = st.split()

result = [f"{w1} {w2}" for w1, w2 in zip(sp, sp[1:])]
print(result)

результат

['This is', 'is a', 'a random', 'random text']

Редактировать

Для больших данных вы можете реализовать генератор.как псевдокод ниже

def get_pair_from_large_text():
    tail_of_last_chunk = ""
    while True
        chunk = get_string_chunk_from_source()
        if len(chunk)==0:
            yield f"{words[-2]} {words[-1]}"
            break
        chunk = tail_of_last_chunk[1] + chunk

        words = split(chunk)
        tail_of_last_chunk = words[-2], words[-1]

        for w1, w2 in zip(words[:-1], words[1:-1])
            yield f"{w1} {w2}"


0 голосов
/ 28 сентября 2019

Но вам действительно нужно регулярное выражение?Вы можете сделать это без регулярных выражений

L1 = line.split(' ')
L2 = L1[1:].append(' ')
Result = [' '.join(a,b) for a,b in zip(L1,L2)]

Используя регулярные выражения, но результат не в порядке

>>> pattern1 = re.compile(r"(\w+\s+\w+)")
>>> pattern2 = re.compile(r"(\s+\w+\s+\w+)")
>>> l1 = re.findall(pattern1, line)
>>> l2 =[x.strip() for x in re.findall(pattern2, line)]
>>> l1
['This is', 'a random']
>>> l2
['is a', 'random text']
>>> l1 + l2
['This is', 'a random', 'is a', 'random text']
0 голосов
/ 28 сентября 2019

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

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