> For the complete documentation index, see [llms.txt](https://olexsyn.gitbook.io/enote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://olexsyn.gitbook.io/enote/progr/python/modules/re.md).

# re

{% embed url="<https://docs.python.org/3/library/re.html>" %}

#### Див. також: [Регулярные выражения в Python от простого к сложному](https://habr.com/ru/articles/349860/) (Хабр)

## match

#### re.match(pattern, string)

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

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

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

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

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

Результат:
AV
```

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

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

Результат:
None
```

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

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

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

## search

#### re.search(pattern, string)

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

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

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

Результат:
Analytics
```

```python
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, якщо рядок не відповідає шаблону; зауважте, що це відрізняється від збігу нульової довжини.

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

## findall

#### re.findall(pattern, string)

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

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

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

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

<pre class="language-python"><code class="lang-python"><strong>any_str = ('+380 (12) 345-6789'
</strong>           '+381 (98) 765-4321')
pat = re.compile('\+(\d+)\s')
res = re.findall(pat, any_str)    # ['380', '381']
</code></pre>

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

```python
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')]
```

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

```python
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])

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

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

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

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

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

Результат:
['Analyt', 'cs V', 'dhya'] # все возможные участки.
```

```python
result = re.split(r'i', 'Analytics Vidhya',maxsplit=1)
print result

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

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

## sub

#### re.sub(pattern, repl, string)

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

```python
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)

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

```python
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']
```

## Приклади

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

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

```python
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`.

```python
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']
```

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

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

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

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

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

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

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

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

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

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

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

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

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

```python
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`):

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

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

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

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

```python
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 і т. д. не потрапили в результат. Змінимо наш код:

```python
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']
```

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

```python
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`для отримання цифр.

```python
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']
```

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

```python
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']
```

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

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

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

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

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

```python
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`для позначення межі слова:

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

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

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

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

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

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

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

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

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

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

```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
```

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

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

```python
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()`для заміни всіх розділів пробілами:

```python
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-файлу:

```html
1NoahEmma2LiamOlivia3MasonSophia4JacobIsabella5WilliamAva6EthanMia7MichaelEmily
```

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

```python
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')]
```

<br>
