Регулярное выражение Python возвращает слова, содержащие двойной символ

#python #regex

Вопрос:

У меня есть большая строка «a», и я хочу извлечь оттуда все слова с двойными символами. Мне нужны слова в качестве выходных данных (не строки или символы). Я пробовал простые вещи, такие как это:

 re.findall(r'b.*([A-Za-z])1.*b', a)
 

который дает список букв.

Я также попробовал это:

 pat='(w*)1'
def f(a, pat):
   pat = r'(w*%sw*)' % pat
   return re.findall(pat, a)
print (f(a,pat))
 

Это дало мне пустой список. Итак, у меня есть две проблемы: 1) Как возвращать слова? 2) Какое регулярное выражение использовать для выбора слов с двойными буквами (например, «посмотрите», «поселитесь» и т.д.).

Комментарии:

1. Ваша первая попытка хороша, но заключите слово в круглые скобки: b(.*([a-zA-Z])1.*)b

2. Тогда это дает мне возможность error: cannot refer to an open group at position 15"

Ответ №1:

Вы можете попробовать это:

 import re


def find_words(text):
    words = re.findall(r'(w*(w)2w*)', text, re.IGNORECASE)
    return words

text = 'look book cat battle settle america google facebook gmail ball'
words = find_words(text=text)

for word, char in words:
    print(f'Word: {word} - Double Char: {char}')
 

Выход:

 Word: look - Double Char: o
Word: book - Double Char: o
Word: battle - Double Char: t
Word: settle - Double Char: t
Word: google - Double Char: o
Word: facebook - Double Char: o
Word: ball - Double Char: l
 

Комментарии:

1. Я думаю, что такие необработанные строки r'(w*(w)2w*)' по-прежнему предпочтительнее, даже если на данный момент это нормально.

2. спасибо за предложение. теперь я думаю, что это будет более общим.

Ответ №2:

Вы можете это сделать:

 import re

def f(a):
   return [x[0] for x in re.findall(r'b([a-z]*([a-z] )2[a-z]*)b', a, re.IGNORECASE)]

print(f("We Choose To Go To The Moon"))
 

Который выведет:

 ['Choose', 'Moon']
 

Это работает, когда есть несколько повторяющихся букв ( success ) или когда повторяющиеся буквы являются разными случаями ( Eel ). Возвращает пустой массив, если в нем нет слов с повторяющимися буквами.

Ответ №3:

1). Образец, который вы пробовали b.*([A-Za-z])1.*b , будет:

  • сопоставьте границу первого слова
  • затем сопоставьте 2 одинаковых символа из диапазонов a-z A-Z в строке
  • затем сопоставьте границу последнего слова, потому .* что может совпадать с любым символом, поэтому все совпадение не ограничивается «словом».

Затем с помощью re.findall будет возвращено только значение группы захвата, которое представляет собой один символ.

2). В шаблоне (w*)1 квантор для символов слова равен 0 или более. Он, например, будет соответствовать всем позициям, так как пустая строка также будет соответствовать, и, возможно, также будет соответствовать 2 раза abc, например abcabc


Вы можете использовать одну группу захвата, а для получения всех совпадений вместо этого используйте re.finditer.

 w*([a-zA-Z])1w*
 

Шаблон совпадает:

  • w* Сопоставьте необязательные символы слов
  • ([a-zA-Z])1 Сопоставьте один символ из диапазонов a-z A-Z, а затем сопоставьте точно такой же символ с помощью обратной ссылки 1
  • w* Сопоставьте необязательные символы слов

Демонстрация регулярных выражений | Демо-версия Python

 import re

pattern = r"w*([a-zA-Z])1w*"
s = 'settle, look, test'
for m in re.finditer(pattern, s):
    print(m.group())
 

Выход

 settle
look