re

match

re.match(pattern, string)

Цей метод шукає за заданим шаблоном на початку рядка. Наприклад, якщо ми викличемо метод match()на рядку «AV Analytics AV» із шаблоном «AV», він завершиться успішно. Але якщо ми шукатимемо Analytics, то результат буде негативний:

import re
result = re.match(r'AV', 'AV Analytics Vidhya AV')
print result

Результат:
<_sre.SRE_Match object at 0x0000000009BE4370>

Шуканий підряд знайдено. Щоб вивести її вміст, застосуємо метод group()(ми використовуємо "r" перед рядком шаблону, щоб показати, що це "сира" рядок у Python):

result = re.match(r'AV', 'AV Analytics Vidhya AV')
print result.group(0)

Результат:
AV

Тепер спробуємо знайти «Analytics» у цьому рядку. Оскільки рядок починається на «AV», метод поверне None:

result = re.match(r'Analytics', 'AV Analytics Vidhya AV')
print result

Результат:
None

Також є методи start()і end()для того, щоб дізнатися про початкову і кінцеву позицію знайденого рядка.

result = re.match(r'AV', 'AV Analytics Vidhya AV')
print result.start()
print result.end()

Результат:
0
2

re.search(pattern, string)

Метод search()шукає по всьому рядку, але повертає лише перший знайдений збіг.

Метод схожий на match(), але шукає не тільки на початку рядка. На відміну від попереднього, search()поверне об'єкт, якщо ми спробуємо знайти "Analytics":

result = re.search(r'Analytics', 'AV Analytics Vidhya AV')
print result.group(0)

Результат:
Analytics
import re

time_str = '1:02:34.05'

res = re.search('^(.+)[\.,](.+)$', time_str)

if res:
    print('res =',res) # res = <re.Match object; span=(0, 10), match='1:02:34.05'>
    print('res.groups() =',res.groups())  # ('1:02:34', '05')
    print('res.group(0) =',res.group(0))  # 1:02:34.05
    print('res.group(1) =',res.group(1))  # 1:02:34
    print('res.group(2) =',res.group(2))  # 05
else:
    print('not found')

fullmatch

re.fullmatch(pattern, string, flags=0)

Якщо весь рядок відповідає шаблону регулярного виразу, повертає відповідний збіг. Повертає None, якщо рядок не відповідає шаблону; зауважте, що це відрізняється від збігу нульової довжини.

if not re.fullmatch('\d\d\d\d', year):
    err = 1

findall

re.findall(pattern, string)

Повертає список усіх знайдених збігів. Метод findall()не має обмежень на пошук на початку або в кінці рядка. Якщо ми шукатимемо «AV» у нашому рядку, він поверне всі входження «AV». Для пошуку рекомендується використовувати саме findall(), тому що він може працювати і як re.search(), і як re.match().

result = re.findall(r'AV', 'AV Analytics Vidhya AV')
print result

Результат:
['AV', 'AV']

Якщо берємо одне входження (), то функція поверне список:

any_str = ('+380 (12) 345-6789'
           '+381 (98) 765-4321')
pat = re.compile('\+(\d+)\s')
res = re.findall(pat, any_str)    # ['380', '381']

Якщо берємо декілька входжень ()()(), то функція поверне список кортежів:

any_str = ('+380 (12) 345-6789'
           '+381 (98) 765-4321')
pat = re.compile('\+(\d+)\s\((\d\d)\)\s(\d{3}\-\d{4})')
res = re.findall(pat, any_str)  #[('380', '12', '345-6789'), ('381', '98', '765-4321')]

в цьому випадку:

for item in res:                    # 1 / 2
	print('found   =',item)     # ('380', '12', '345-6789') / ('381', '98', '765-4321')
	print('country =',item[0])  # 380 / 381
	print('city    =',item[1])  # 12 / 98
	print('number  =',item[2])  # 345-6789 / 765-432

split

re.split(pattern, string, [maxsplit = 0])

Цей метод поділяє рядок за заданим шаблоном.

result = re.split(r'y', 'Analytics')
print result

Результат:
['Anal', 'tics']

У прикладі ми розділили слово "Analytics" за літерою "y". Метод split()приймає також аргумент maxsplitзі значенням за умовчанням, рівним 0. У разі він розділить рядок стільки разів, скільки можливо, але якщо вказати цей аргумент, то поділ буде зроблено трохи більше зазначеної кількості раз. Давайте подивимося на приклади Python RegEx:

result = re.split(r'i', 'Analytics Vidhya')
print result

Результат:
['Analyt', 'cs V', 'dhya'] # все возможные участки.
result = re.split(r'i', 'Analytics Vidhya',maxsplit=1)
print result

Результат:
['Analyt', 'cs Vidhya']

Ми встановили параметр maxsplitрівним 1 і в результаті рядок був розділений на дві частини замість трьох.

sub

re.sub(pattern, repl, string)

Шукає шаблон у рядку та замінює його на вказаний підрядок. Якщо шаблон не знайдено, рядок залишається незмінним.

result = re.sub(r'India', 'the World', 'AV is largest Analytics community of India')
print result

Результат:
'AV is largest Analytics community of the World'

compile

re.compile(pattern, repl, string)

Ми можемо зібрати регулярне вираження в окремий об'єкт, який можна використовувати для пошуку. Це також позбавляє переписування одного і того ж виразу.

pattern = re.compile('AV')
result = pattern.findall('AV Analytics Vidhya AV')
print result
result2 = pattern.findall('AV is largest analytics community of India')
print result2

Результат:
['AV', 'AV']
['AV']

Приклади

Повернути перше слово з рядка

Спочатку спробуємо витягнути кожен символ (використовуючи .)

result = re.findall(r'.', 'AV is largest Analytics community of India')
print result

Результат:
['A', 'V', ' ', 'i', 's', ' ', 'l', 'a', 'r', 'g', 'e', 's', 't', ' ', 'A', 'n', 'a', 'l', 'y', 't', 'i', 'c', 's', ' ', 'c', 'o', 'm', 'm', 'u', 'n', 'i', 't', 'y', ' ', 'o', 'f', ' ', 'I', 'n', 'd', 'i', 'a']

Для того, щоб у кінцевий результат не потрапив пробіл, використовуємо . \w.

result = re.findall(r'\w', 'AV is largest Analytics community of India')
print result

Результат:
['A', 'V', 'i', 's', 'l', 'a', 'r', 'g', 'e', 's', 't', 'A', 'n', 'a', 'l', 'y', 't', 'i', 'c', 's', 'c', 'o', 'm', 'm', 'u', 'n', 'i', 't', 'y', 'o', 'f', 'I', 'n', 'd', 'i', 'a']

Тепер спробуємо дістати кожне слово (використовуючи *або +)

result = re.findall(r'\w*', 'AV is largest Analytics community of India')
print result

Результат:
['AV', '', 'is', '', 'largest', '', 'Analytics', '', 'community', '', 'of', '', 'India', '']

І знову в результат потрапили прогалини, оскільки *означає «нуль чи більше символів». Для того, щоб їх прибрати, використовуємо +:

result = re.findall(r'\w+', 'AV is largest Analytics community of India')
print result
Результат:
['AV', 'is', 'largest', 'Analytics', 'community', 'of', 'India']

Тепер витягнемо перше слово, використовуючи ^:

result = re.findall(r'^\w+', 'AV is largest Analytics community of India')
print result

Результат:
['AV']

Якщо ми використовуємо $замість ^, ми отримаємо останнє слово, а чи не перше:

result = re.findall(r'\w+$', 'AV is largest Analytics community of India')
print result

Результат:
[‘India’]

Повернути перші два символи кожного слова

Варіант 1: використовуючи \w, витягнути два послідовні символи, крім пробельних, з кожного слова:

result = re.findall(r'\w\w', 'AV is largest Analytics community of India')
print result

Результат:
['AV', 'is', 'la', 'rg', 'es', 'An', 'al', 'yt', 'ic', 'co', 'mm', 'un', 'it', 'of', 'In', 'di']

Варіант 2: витягнути два послідовні символи, використовуючи символ межі слова ( \b):

result = re.findall(r'\b\w.', 'AV is largest Analytics community of India')
print result

Результат:
['AV', 'is', 'la', 'An', 'co', 'of', 'In']

Повернути домени зі списку email-адрес

Спочатку повернемо всі символи після "@":

result = re.findall(r'@\w+', 'abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz')
print result

Результат:
['@gmail', '@test', '@analyticsvidhya', '@rest']

Як бачимо, частини .com, .in і т. д. не потрапили в результат. Змінимо наш код:

result = re.findall(r'@\w+.\w+', 'abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz')
print result

Результат:
['@gmail.com', '@test.in', '@analyticsvidhya.com', '@rest.biz']

Другий варіант - витягти тільки домен верхнього рівня, використовуючи групування - ( ):

result = re.findall(r'@\w+.(\w+)', 'abc.test@gmail.com, xyz@test.in, test.first@analyticsvidhya.com, first.test@rest.biz')
print result

Результат:
['com', 'in', 'com', 'biz']

Витягти дату з рядка

Використовуємо \dдля отримання цифр.

result = re.findall(r'\d{2}-\d{2}-\d{4}', 'Amit 34-3456 12-05-2007, XYZ 56-4532 11-11-2011, ABC 67-8945 12-01-2009')
print result

Результат:
['12-05-2007', '11-11-2011', '12-01-2009']

Для отримання лише року нам знову допоможуть дужки:

result = re.findall(r'\d{2}-\d{2}-(\d{4})', 'Amit 34-3456 12-05-2007, XYZ 56-4532 11-11-2011, ABC 67-8945 12-01-2009')
print result

Результат:
['2007', '2011', '2009']

Витягти слова, що починаються на голосну

Спочатку повернемо всі слова:

result = re.findall(r'\w+', 'AV is largest Analytics community of India')
print result

Результат:
['AV', 'is', 'largest', 'Analytics', 'community', 'of', 'India']

А тепер — лише ті, які починаються на певні літери (використовуючи []):

result = re.findall(r'[aeiouAEIOU]\w+', 'AV is largest Analytics community of India')
print result

Результат:
['AV', 'is', 'argest', 'Analytics', 'ommunity', 'of', 'India']

Вище ми бачимо обрізані слова «argest» та «ommunity». Для того, щоб прибрати їх, використовуємо \bдля позначення межі слова:

result = re.findall(r'\b[aeiouAEIOU]\w+', 'AV is largest Analytics community of India')
print result

Результат:
['AV', 'is', 'Analytics', 'of', 'India']

Також ми можемо використовувати ^всередині квадратних дужок для інвертування групи:

result = re.findall(r'\b[^aeiouAEIOU]\w+', 'AV is largest Analytics community of India')
print result

Результат:
[' is', ' largest', ' Analytics', ' community', ' of', ' India']

В результаті потрапили слова, що «починаються» з пробілу. Приберемо їх, включивши пробіл у діапазон у квадратних дужках:

result = re.findall(r'\b[^aeiouAEIOU ]\w+', 'AV is largest Analytics community of India')
print result

Результат:
['largest', 'community']

Перевірити формат телефонного номера

Номер має бути довжиною 10 знаків і починатися з 8 або 9. Є список телефонних номерів, і потрібно перевірити їх, використовуючи регулярки в Python:

li = ['9999999999', '999999-999', '99999x9999']

for val in li:
    if re.match(r'[8-9]{1}[0-9]{9}', val) and len(val) == 10:
        print 'yes'
    else:
        print 'no'

Результат:
yes
no
no

Розбити рядок за кількома роздільниками

Можливе рішення:

line = 'asdf fjdk;afed,fjek,asdf,foo' # String has multiple delimiters (";",","," ").
result = re.split(r'[;,\s]', line)
print result

Результат:
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']

Також ми можемо використовувати метод re.sub()для заміни всіх розділів пробілами:

line = 'asdf fjdk;afed,fjek,asdf,foo'
result = re.sub(r'[;,\s]',' ', line)
print result

Результат:
asdf fjdk afed fjek asdf foo

Вийняти інформацію з html-файлу

Допустимо, потрібно витягти інформацію з html-файлу, укладену між <td>і </td>, крім першого стовпця з номером. Також вважатимемо, що html-код міститься у рядку.

Приклад вмісту html-файлу:

1NoahEmma2LiamOlivia3MasonSophia4JacobIsabella5WilliamAva6EthanMia7MichaelEmily

За допомогою регулярних виразів у Python це можна вирішити так (якщо помістити вміст файлу в змінну test_str):

result = re.findall(r'\d([A-Z][A-Za-z]+)([A-Z][A-Za-z]+)', test_str)
print result

Результат:
[('Noah', 'Emma'), ('Liam', 'Olivia'), ('Mason', 'Sophia'), ('Jacob', 'Isabella'), ('William', 'Ava'), ('Ethan', 'Mia'), ('Michael', 'Emily')]

Last updated