Различия между функциями findall (), match () и search () во встроенном модуле регулярных выражений Python.

Регулярные выражения, также известные как Regex, пригодятся во множестве сценариев обработки текста. Вы можете искать шаблоны цифр, букв, знаков препинания и даже пробелов. Regex работает быстро и помогает избежать ненужных циклов в вашей программе для сопоставления и извлечения желаемой информации. До недавнего времени я чувствовал, что Regex очень сложен, синтаксис выглядит разочаровывающим, и думал, что я не смогу узнать о нем. Как и многие другие, мы разделяем это чувство.

Прочитав множество ресурсов в Интернете, я решил использовать этот пост, чтобы показать, как можно использовать модуль re в Python для решения определенных проблем с помощью функции findall (), и кратко представить функции match () и search (); все они похожи, но используются по-разному.

Использование регулярных выражений в Python

Чтобы начать использовать Regex в Python, вам сначала нужно импортировать модуль «re» Python.

import re

Этот пост разделен на три раздела, в которых рассматриваются три простые функции для извлечения полезной информации из строк с примерами.

  • найти все()
  • соответствие()
  • поиск()

re.findall (): поиск всех совпадений в строке / списке

Функция findall () в Regex чрезвычайно полезна, поскольку она возвращает список строк, содержащих все совпадения. Если шаблон не найден, re.findall () возвращает пустой список. Посмотрим, когда можно будет использовать функцию findall ()!

  1. Извлечь все вхождения определенных слов

Используя следующий текстовый абзац, описывающий, как Рей, африканский пингвин, и Роза, старейшая калан в аквариуме Монтерей-Бей, нуждаются в глазных каплях.

aquarium='Because of problems with her eyesight, rey the African penguin had issues with swimming. That’s unusual for a penguin, and presented a big challenge for our aviculture team to help Rey overcome her hesitancy. Slowly and steadily, we trained her to be comfortable feeding in the water like the rest of the penguin colony. The aviculturists also trained Rey to accept daily eye drops from them as part of her special health care. Rey already had good relationships with some staff, and was comfortable with them handling her. Senior Aviculturist Kim Fukuda says the team built on those bonds to get Rey used to receiving the eye drops. "She knows the routine," Kim says. "I usually give her the eye drops in one area of the exhibit after all the penguins get their vitamins. When that happens, she runs over there and waits for me." Rosa, our oldest sea otter, has very limited eyesight, among other health issues. The sea otter team had already trained Rosa so they could examine her eyes, and built on that trust to include administering the eye drops she needs.'

Теперь вы хотите извлечь все вхождения Rey из текста, для чего вы должны сделать что-то вроде этого:

rey_occurences = "Rey"
re.findall(rey_occurences, aquarium)
# Output
['Rey', 'Rey', 'Rey', 'Rey']

Функция findall () принимает два параметра: первый - это шаблон, по которому выполняется поиск, в нашем случае rey_occurrences, а второй параметр - это текст, который мы ищем, в нашем случае. , аквариум. Как видите, эта функция возвращает все неперекрывающиеся совпадения шаблона, который находится в переменных rey_occurrences, из второго параметра aquarium.

Но подождите, есть еще одна причина, которой не было учтено. Это произошло потому, что по умолчанию регулярные выражения чувствительны к регистру, поэтому наша функция findall () не возвращала «rey», потому что это строчные, а не прописные буквы, как это было определено в rey_occurrences переменные. Мы можем отредактировать наш предыдущий код, чтобы он включал строчные значения искомого шаблона, включив третий параметр, flags, который можно использовать по разным причинам, например, позволяя шаблонам вместо этого соответствовать определенным строкам. всего текста, сопоставление шаблонов, охватывающих несколько строк, и сопоставление без учета регистра. В наших целях мы будем использовать флаг re.IGNORECASE, чтобы игнорировать регистр при выполнении поиска.

rey_occurences = "Rey"
re.findall(rey_occurences,aquarium,flags=re.IGNORECASE)
# Output
['rey', 'Rey', 'Rey', 'Rey', 'Rey']

Мы также можем искать по нескольким шаблонам и извлекать все вхождения этих шаблонов. В нашем текущем тексте давайте также найдем вхождения «Rosa», просто используя | оператор для создания шаблона.

sea_animals="Rey|Rosa"
re.findall(sea_animals,aquarium,flags=re.IGNORECASE)
# Output
['rey', 'Rey', 'Rey', 'Rey', 'Rey', 'Rosa', 'Rosa']

| Оператор - это специальный символ, который указывает Regex искать в тексте шаблон один или шаблон два. Если вы хотите найти вхождение «|» в свой текст, вам нужно будет добавить его в свой шаблон с обратной косой чертой, «\ | ». Эта обратная косая черта указывает Regex прочитать | оператор как символ без вывода его специального значения.

2. Извлечение слов, содержащих только алфавиты

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

gifts = "\
Basketball    2    25.63\
Tshirt     4   53.92\
Sneakers    1    30.58\
Mask    10   80.54\
GiftCard    2    50.00"

Допустим, вы хотите извлечь только слова; мы можем сделать это, используя специальные последовательности и наборы Regex, чтобы указать шаблон, который мы ищем. Этот полезный сайт предоставляет красивую шпаргалку по Regex.

words = '[a-z]+'
re.findall(words,gifts,flags=re.IGNORECASE)
# Output
['Basketball', 'Tshirt', 'Sneakers', 'Mask', 'GiftCard']

Устанавливая наш шаблон на [a-z], это означает класс символов от «a» до «z», в то время как оператор + соответствует одному или нескольким повторениям предыдущего регулярного выражения или класса, которым в нашем случае является [a-z]. Обратите внимание, что шаблон [a-z] по-прежнему возвращает прописные буквы, это из-за нашего флага re.IGNORECASE.

3. Извлечение всех вхождений чисел.

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

text = "Sixty-six undergraduate students from an urban college in New York City participated in this study. Students participated in this research study as part of a requirement for a class. Nineteen participants were excluded from the study for meeting one or more exclusion criteria including not completing the sentence unscrambling task, not providing ratings for each of the traits, or failing either one of the two attention checks, leaving the total number of eligible participants at forty-seven. Participants included 36 women aged 18 to 52 years old (M = 20.52, SD = 6.97), 10 men aged 18 to 28 years old (M = 23.5, SD = 12.36), and one individual who did not disclose their sex."
numbers="\d+"
re.findall(numbers,text)
# Output
['36', '18','52','20', '52','6','97','10','18','28','23','5','12','36']

Установив для нашего шаблона значение \ d, это означает одну цифру, в то время как оператор + будет включать повторение цифр. Как вы можете видеть из нашего текста, у нас также есть десятичные дроби, но в нашем выводе они были разделены знаком «.» Мы можем исправить это, используя следующее регулярное выражение:

all_numbers="\d+\.*?\d+"
re.findall(all_numbers,text)
# Output
['36', '18', '52', '20.52', '6.97', '10', '18', '28', '23.5', '12.36']

Как мы видели ранее, шаблон \ d + захватит одну цифру, за которой следуют повторения цифр, включая десятичные дроби, мы используем шаблон. *? будет искать совпадение, используя как можно меньше символов.

4. Извлечение слов, за которыми следует определенный шаблон

С текстовыми данными могут быть моменты, когда вам нужно извлечь слова, за которыми следует специальный символ, например @, для имен пользователей или кавычек в заданном тексте.

В тексте нашего аквариума есть две кавычки, давайте извлечем их из текста.

quotes='"(.*?)"'
re.findall(quotes,aquarium)
# Output
['She knows the routine,',
 'I usually give her the eye drops in one area of the exhibit after all the penguins get their vitamins. When that happens, she runs over there and waits for me.']

Мы устанавливаем наш шаблон на «(. +?)», Где одинарные кавычки представляют тело текста, а двойные кавычки представляют кавычки внутри текста. У нас есть круглые скобки, которые создают группу захвата и. *? является не жадным модератором и извлекает только кавычки, а не текст между кавычками.

Как видите, функция findall () модуля Python Regex может быть очень полезной при поиске списка со всеми необходимыми совпадениями. Эту функцию иногда путают с функциями match () и search () одного и того же модуля. Давайте кратко обсудим разницу.

re.match (): возвращает первое вхождение в текст

В то время как re.findall () возвращает совпадения подстроки, найденной в тексте, re.match () выполняет поиск только с начала строки и возвращает соответствующий объект, если он найден. Однако если совпадение найдено где-то в середине строки, оно не вернет.

Выражения «w +» и «\ W» будут соответствовать словам, начинающимся с буквы «r», и после этого все, что не начинается с «r», не идентифицируется. Чтобы проверить соответствие для каждого элемента в списке или строке, мы запускаем цикл в этом примере Python re.match ():

list = ["red rose", "ruby red", "pink peony"]
# Loop.
for element in list:
    m = re.match("(r\w+)\W(r\w+)", element)
if m:
        print(m.groups())
# Output
('red', 'rose')
('ruby', 'red')

re.search (): поиск шаблона в тексте

Функция re.search () будет искать шаблон регулярного выражения и возвращать первое вхождение. В отличие от Python re.match (), он проверяет все строки входной строки. Если шаблон найден, будет возвращен соответствующий объект, в противном случае возвращается «null».

patterns=['penguin','Rosa']
aquarium_short="Because of problems with her eyesight, rey the African penguin had issues with swimming."
for pattern in patterns:
    print('Looking for "%s" in "%s" = '% (pattern, aquarium_short), end=" ")
    
    if re.search(pattern, aquarium_short):
        print("Match was found")
    else:
        print("No match was found")
# Output
Looking for "penguin" in "Because of problems with her eyesight, rey the African penguin had issues with swimming." =  Match was found
Looking for "Rosa" in "Because of problems with her eyesight, rey the African penguin had issues with swimming." =  No match was found

В этом примере мы искали две строки: «пингвин» и «Роза» в текстовой строке «Из-за проблем со зрением у африканского пингвина Рей были проблемы с плаванием». Для «пингвина» мы нашли совпадение, поэтому он возвращает результат «Совпадение найдено», в то время как слово «Роза» не было найдено в строке и возвращает «Совпадение не найдено».

В то время как re.search () ищет первое совпадение в строке, re.findall () ищет все вхождения match, а re.search () соответствует началу строки, а не началу каждой строки. Дополнительные операции, которые можно использовать с модулем Python Regex, см. В документации.



Я надеюсь, что это было полезно! Спасибо за чтение! :)