Python регулярное выражение: сопоставить любые повторяющиеся слова, которые разделены ровно одним другим словом - PullRequest
2 голосов
/ 15 марта 2020

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

Так что если:

"all in all" вернется: "all"

"good good good" вернется: Null (То же слово, а не другое слово)

Я пытался:

p = re.compile(r'(\b\w+\b)\s\w+\s\1')
m = p.findall('all in all day in and day out bit by bit good good good')

print(m)

Это возвращает ['all', 'bit', 'good'], но я только хочу, чтобы он возвратил ['all','bit'].

Заранее спасибо!

Ответы [ 2 ]

7 голосов
/ 15 марта 2020

Вам просто нужно добавить отрицательный запрос для слова, следующего сразу за начальной группой захвата, чтобы убедиться, что ваше регулярное выражение не может соответствовать (например) good good:

import re

p = re.compile(r'(\b\w+\b)(?!\s\1\b)\s\w+\s\1\b')
m = p.findall('all in all day in and day out bit by bit good good good')

print(m)

Вывод:

['all', 'bit']

Если вы хотите включить перекрывающиеся совпадения, сделайте регулярное выражение положительным взглядом (спасибо @ggorlen):

p = re.compile(r'(?=(\b\w+\b)(?!\s\1\b)\s\w+\s\1\b)')
m = p.findall('foo bar foo bar foo')

Вывод:

['foo', 'bar', 'foo']

Если вы также необходимо удалить дубликаты совпадений, преобразовать в set и обратно в list:

p = re.compile(r'(?=(\b\w+\b)(?!\s\1\b)\s\w+\s\1\b)')
m = list(set(p.findall('foo bar foo bar foo')))
print(m)

Вывод:

['foo', 'bar']
3 голосов
/ 15 марта 2020

Нет необходимости в регулярных выражениях; нормальные программные конструкции могут справиться с такой проблемой просто отлично. Напишите al oop и добавьте условное выражение:

s = 'all in all day in and day out bit by bit good good good'

words = s.split()
result = []

for i in range(len(words) - 2):
    if words[i] == words[i+2] and words[i] != words[i+1]:
        result.append(words[i])

print(result) # ['all', 'bit']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...