Разное

Regexp python: Python RegEx (With Examples)

Содержание

Руководство по использованию регулярных выражений Python | by Iuliia Averianova | NOP::Nuances of Programming

Первое, что нужно освоить в работе с регулярными выражениями, — это создание паттернов.

Рассмотрим некоторые наиболее часто используемые паттерны.

Простейший паттерн — это просто строка.

pattern = r'times'string = "It was the best of times, it was the worst of times."print(len(re.findall(pattern,string)))

Но это не очень полезно. Для создания сложных паттернов регулярные выражения содержат специальные символы/операторы. Давайте рассмотрим эти операторы по очереди.

1. Оператор “[ ]"

Этот оператор использовался в первом примере. Мы ищем любой из символов в квадратных скобках.

[abc]— найдет a, b, и c.

[a-z]— найдет все значения от a до z.

[a-z0–9A-Z]— найдет значения от a до z, от A до Z и от 0 до 9.

В Python этот паттерн использовать легко:

pattern = r'[a-zA-Z]'string = "It was the best of times, it was the worst of times."print(len(re.findall(pattern,string)))

В регулярных выражениях есть и другие функции, кроме .findall , но мы вернемся к ним чуть позже.

2. Оператор точки

Оператор точки (.) используется для поиска соответствия любому единичному символу, кроме символа новой строки.

Самое классное в этом операторе то, что его можно использовать в сочетании с другими.

Например, нужно найти в строке подстроки длиной в 6 знаков, начинающиеся с маленькой “d” и заканчивающиеся маленькой “e”.

3. Некоторые метапоследовательности

Некоторые паттерны используются постоянно. Для них существуют шорткаты. Вот самые часто используемые:

\w — соответствие любой букве, цифре или подчеркиванию, эквивалентен [a-zA-Z0–9_].

\W — соответствие любому символу, кроме буквенного и цифрового символа и знака подчёркивания.

\d — соответствие любому цифровому символу, эквивалентен [0–9].

\D — соответствие любому нецифровому символу.

4. Операторы “+” и “*”

Символ точки используется для поиска единичного символа. Что если нам нужно найти больше?

Символ + используется для 1 или более значений крайнего левого символа.

Символ * используется для 0 или более значений крайнего левого символа.

Например, если нужно найти все подстроки, начинающиеся с “d” и заканчивающиеся на “e”, нам может встретиться ноль или более символов между “d” и “e”. Используем: d\w*e

Если нужно найти все подстроки, начинающиеся с “d” и заканчивающиеся на “e” с как минимум одним символом между “d” и “e”, используем: d\w+e

Также можно применить более общий подход с добавлением “{ }”

\w{n} — повторяет \w ровно n раз.

\w{n,} — повторяет \w хотя бы n раз или более.

\w{n1, n2} — повторяет \w хотя бы n1 раз, но не более n2 раз.” выделяет начало строки, а “$” выделяет конец строки.

6. Границы слов

Вы заметили, что в примерах выше я всегда выделял подстроки, а не слова?

Что если нужно найти все слова, начинающиеся с “d”?

Можно ли использовать паттерн d\w*? А давайте посмотрим.

основы NLP и Data Science

Регулярные выражения (regular expressions) являются важнейшим инструментом для многих задач NLP в Python. Сегодня мы расскажем об основных функциях Python-модуля re. Читайте в этой статье: как с помощью регулярных выражений найти нужные символы, как посчитать количество вхождений, а также как заменить одну подстроку на другую в Python

Зачем нужны регулярные выражения

Регулярные выражения — последовательность символов, которая определяет шаблон поиска. Например, для задач NLP это может быть поиск именованных сущностей (для такой задачи может подойти Python-библиотека Yargy). Представим себе выражение:

Python is cool

Требуется извлечь из него слово «cool». Казалось бы, сделать это очень просто, достаточно передать это слово в Python-функцию с регулярным выражением. Но поскольку это набор символов, то выражения, которые содержат этот набор также сработают:

Python is coolest
I have a watercooler
Python is supercool
Регулярные выражения в Python

Для работы с регулярными выражениями в Python используется модуль re (сокращено от regular expression). В нем содержится 4 основные функции: search, match, findall, finditer, а также sub Причём у первых 4-х одинаковая сигнатура — принимают на вход шаблон и выражение. Обращаясь к предыдущему примеру, шаблоном является «cool». Функция sub дополнительно принимает на вход строку для замены.

Ищем первый попавшийся шаблон с search

Функция search найдёт в выражении первый попавшийся шаблон. Нам нужно найти шаблон, который состоит из последовательности символов c, o, o, l. Поэтому передаём в функцию этот шаблон и выражение. Такое регулярное выражение в Python выглядит следующим образом:

>>> import re
>>> expr = 'Python is cool'
>>> pattern = 'cool'
>>> re.search(pattern, expr)
<re.Match object; span=(10, 14), match='cool'>

Мы получили объект Match, а span показывает индексы шаблона в выражении. Поэтому его так же можно извлечь в Python:

>>> expr[10:14]
'cool'

Заметим, что функция search находит только первый попавшийся шаблон, дальше она уже не смотрит:

>>> expr = 'Python is cool, very cool'
>>> re.search(pattern, expr)
<re.Match object; span=(10, 14), match='cool'>

Также не забываем, что шаблон — это последовательность символов, а не само слово. Например, ниже показано, как в Python находится последовательность «cool» в составном слове.

>>> expr = 'I have a watercooler'
>>> re.search('cool', expr)
<re.Match object; span=(14, 18), match='cool'>
Ищем все вхождения с findall и finditer

В отличие от функции search, две других findall и finditer вернут все найденные вхождения. Отличаются findall и finditer друг от друга тем, что первый возвращает список (list), а второй итератор (iterator), о котором говорили тут. Возвращаясь к предыдущему примеру, регулярное выражение  для нахождения всех совпадений в Python будет выглядеть так:

>>> expr = 'Python is cool, very cool'
>>> re.findall('cool', expr)
['cool', 'cool']
>>> re.finditer('cool', expr)
<callable_iterator object at 0x7fe095db00d0>

С помощью функции findall можно посчитать количество шаблонов во всей строке:

>>> len(re.findall('cool', expr))
2
Проверяем начало строки с match

Функция match проверит начало строки на содержание шаблона. Пример выше не начинается с cool, поэтому эта функция вернёт None. С другой стороны, если выражение начинается с шаблона, то функция match вернёт объект Match. Рассмотрите следующие регулярные выражения в Python:

>>> expr = 'Python is cool'
>>> re.match('Python', expr)
<re.Match object; span=(0, 6), match='Python'>
>>> re.match('cool', expr) is None
True
Исключаем шаблон из строки с sub

Ещё одной полезной функцией Python-модуля re является sub. Она необходима, когда один шаблон нужно заменить на другой и пригодится для подготовки текстов перед применением NLP-методов в Python, например, для избавления от всех цифр, знаков препинания и символов. К сигнатуре этой функции добавляется аргумент repl — на какую строку заменяем. Ниже регулярные выражения в Python это демонстрируют. Обратите внимание, что sub возвращает строку, поэтому их стоит переприсвоить.

>>> expr = 'Python is cool, very cool'
>>> pattern = 'cool'
>>> repl = 'slow'
>>> re.sub(pattern, repl, expr)
'Python is slow, very slow'

Также отметим, что функция заменяет все вхождения. Если требуется ограничить это число, то оно указывается в аргументе count.

>>> re.sub(pattern, repl, expr, count=1)
'Python is slow, very cool'

 

Ещё больше подробностей о работе регулярных выражения в Python на реальных примерах  Data Science задач, вы узнаете на нашем специализированном курсе «PNLP: NLP – обработка естественного языка с Python» в лицензированном учебном центре обучения и повышения квалификации Data Scientist’ов и IT-специалистов в Москве.

Источники

  1. https://docs.python.org/3/howto/regex.html

Шпаргалка по Python RegEx для начинающих программистов

Распечатать() Отобразить результат выполнения команды x = «Привет, мир»
печать (х)

вывод: Привет, мир

ввод () Сбор отзывов пользователей print (input («как тебя зовут?»))

вывод: как вас зовут?

тип() Найдите тип переменной x = «Регулярные выражения»
тип (x)

выход:

len () Найдите количество элементов в переменной len ([1, 2, 3])

вывод: 3

Экранировать символ, изменяющий назначение строки кода print («Я хочу, чтобы вы добавили » «»)

вывод: я хочу, чтобы вы добавили «»

п Разорвать строковый символ, чтобы начать со следующей строки print («Это строка n Это вторая строка»)

выход:
Это линия
Это вторая строка

def имя_функции (параметр):
команды
Инициировать функцию с необязательным параметром def yourName (x):
печать (x + 1)
лямбда Вызов анонимной функции add_3_to = лямбда y: y + 3
печать (add_3_to (4))

вывод: 7

возвращение Вернуть результат из функции def yourName (x):
вернуть x + 1
класс Создать объект Python класс myClass:
def myFunc (x):
def __init__ Инициализировать атрибуты класса класс myClass:
def __init __ (себя, атрибуты …)
«__init__.py Сохраните файл, содержащий модуль, чтобы он успешно читался в другом файле Python Переименуйте файл, содержащий модуль, как:

«__init__.py

int () Преобразование переменной в целое число интервал (1,234)

вывод: 1

str () Преобразовать переменную в строку ул (1.234)

вывод: ‘1.234’

float () Преобразование переменной в число с плавающей запятой поплавок (23)

вывод: 23.0

dict (Счетчик ()) Преобразование списка или кортежа в словарь после сортировки с помощью встроенного счетчика Python из коллекций счетчик импорта
dict (Counter ([1,1,2,1,2,3,3,4]))

вывод: {1: 3, 2: 2, 3: 2, 4: 1}

круглый() Округлите результат операции до ближайшего целого числа круглый (23,445)

вывод: 23

раунд (операция или число, десятичные знаки) Округлите результат операции до определенного количества десятичных знаков круглый (23,4568, 2)

вывод: 23,46

если: Инициировать условный оператор если 2 <3:
print («Два меньше»)
Элиф: Сделайте контрзадачу, если оператор if имеет значение False если 2 <3:
print («Два меньше»)
elif 2 == 3:
print («Продолжайте»)
еще: Сделайте последнее возражение, если другие условия неверны. если 2 <3:
print («Два меньше»)
elif 2 == 3:
print («Продолжайте»)
еще:
print («Три больше»)
Продолжать Игнорировать условие и выполнить оставшуюся часть цикла a = [1, 4, -10, 6, 8]
для b в a:
если b <= 0:
Продолжать
печать (б)

выход:
1
4
6
8

перемена Завершить поток цикла с заданным условием a = [1, 4, -10, 6, 8]
для b в a:
если b> = 6:
перемена
печать (б)

выход:
1
4
-10

проходят Игнорировать предыдущие инструкции для b в a:
проходят
попробуй, кроме Попробуйте блок кода, иначе вызовите определенное исключение пытаться:
печать (а)

Кроме:
print («Произошла ошибка!»)

вывод: Произошла ошибка!

наконец-то Выполнить последний код, когда блоки try и except терпят неудачу пытаться:
печать (а)

Кроме:
печать (d)
наконец-то:
print («Вы не можете распечатать неопределенную переменную»)

вывод: вы не можете распечатать неопределенную переменную

поднять исключение () Вызвать исключение, которое останавливает команду, когда выполнение невозможно а = 7 + 2
если <10:
поднять исключение («Ой! Вы не получили 10 баллов»)
импорт x Импортировать целый модуль или библиотеку импорт математики
из x импорт y Импортировать библиотеку x из файла или класс y из режима импорта scipy.stats
в качестве Настройте выражение под ваше предпочтительное имя импортировать панд как pd
в Проверить, присутствует ли значение в переменной х = [1, 4, 6, 7]
если 5 в x:
print («Есть пятерка»)
еще:
print («Пятерки нет»)

вывод: Нет пятерки

является Проверьте, относятся ли две переменные к одному элементу х = [1, 4, 6, 7]
х = б
print (x is b)
Правда
Никто Объявить нулевое значение x = Нет
< Проверить, меньше ли одно значение другого 5 <10

вывод: True

> Проверьте, не превышает ли одно значение другое 5> 10

вывод: Ложь

<= Проверить, меньше ли одно значение другому или равно ему 2 * 2 <= 3

вывод: Ложь

> = Проверить, больше ли одно значение другому или равно ему 2 * 2> = 3

вывод: True

«== Проверьте, совпадает ли одно значение с другим 3 == 4

вывод: ложь

знак равно Убедитесь, что одно значение не равно другому 3! = 4

вывод: True

импорт ре Импортировать встроенные регулярные выражения Python импорт ре
re. Привет», someText)
печать (а)

вывод: [‘Привет’]

string.index () Проверить позицию индекса строкового символа a = «Привет, мир»
a.index (‘H’)

вывод: 0

string.capitalize () Сделать первый символ в наборе строк заглавным a = «Привет, мир»
a.capitalize ()

вывод: ‘Hello world’

string.swapcase () Выведите первую букву каждого слова в нижнем регистре, а остальные в верхнем регистре a = «Привет, мир»
a.swapcase ()

выход:
‘Привет мир’

string.lower () Преобразуйте все строки в нижний регистр a = «Привет, мир»
а. нижний ()

вывод: ‘привет, мир’

string.upper () Преобразовать все строки в верхний регистр a = «Привет, мир»
a.upper ()

вывод: ‘HELLO WORLD’

string.startswith () Проверить, начинается ли строка с определенного символа a = «Привет, мир»
a.startswith (‘а’)

вывод: Ложь

string.endswith () Проверить, заканчивается ли строка определенным символом a = «Привет, мир»
a.endswith (‘д’)

вывод: True

string.split () Разделите каждое слово на список a = «Привет, мир»
a.split ()

вывод: [‘Привет’, ‘мир’]

строки {} ‘. format () Отображать вывод в виде строки а = 3 + 4
print («Ответ: {}». формат (а))

вывод: Ответ 7

не Нет Проверить, не пусто ли значение переменной def checknull (a):
если a не равно None:
вернуть «его полный!»
еще:
вернуть «его пусто!»
х% у Найдите остаток (модуль) от деления 9% 4

вывод: 1

х // у Найдите частное от деления 9 // 4

вывод: 2

знак равно Присвойте значение переменной а = {1: 5, 3: 4}
«+ Сложите элементы вместе [«два»] + [«один»]

вывод: [‘два’, ‘один’]

1 + 3

output = 4

«- Найдите разницу между набором чисел 3-4

output = -1

«* Найдите произведение набора чисел 3 * 4

вывод: 12

а + = х Добавьте x к переменной a, не присваивая его значение новой переменной а = 2
а + = 3

вывод: 5

а- = х Вычтите x из переменной a, не присваивая его новой переменной а = 3
а- = 2

вывод: 1

а * = х Найдите произведение переменных a и x без присвоения результата новой переменной а = [1, 3, 4]
а * = 2

вывод: [1, 3, 4, 1, 3, 4]

х ** у Возвести основание x в степень y 2 ** 3

вывод: 8

pow (x, y) Возвести x в степень y pow (2, 3)

вывод: 8

абс (х) Преобразуйте отрицательное целое число в его абсолютное значение абс (-5)

вывод: 5

х ** (1 / нт) Найдите корень n-й степени числа 8 ** (1/3)

вывод: 2

а = б = с = д = х Присвойте одно и то же значение нескольким переменным a = b = c = d = «Привет, мир»
х, у = у, х Поменять местами переменные х = [1, 2]
у = 3
х, у = у, х
печать (х, у)

выход:
3 [1, 2]

за Перебирать элементы в переменной а = [1, 3, 5]
для b в a:
print (b, «x», «2», «=», b * 2)

выход:
1 х 2 = 2
3 х 2 = 6
5 х 2 = 10

пока Продолжайте перебирать переменную, пока конкретное условие остается истинным а = 4
b = 2
а b <= a:
print (b, «меньше», a)
б + = 1

выход:
2 меньше 4
3 меньше 4
4 меньше 4

спектр() Создайте диапазон положительных целых чисел от x до y x = диапазон (4)
печать (х)
диапазон (0, 4)
для b в x:
печать (б)

выход:
0
1
2
3

сумма () Перебирать элементы в списке print (sum ([1, 2, 3]))

вывод: 6

сумма (список, начало) Вернуть сумму списка с добавленным элементом print (sum ([1, 2, 3], 3))

вывод: 9

[] Составьте список элементов x = [‘a’, 3, 5, ‘h’, [1, 3, 3], {‘d’: 3}]
() Создайте туппл — тупплы неизменны х = (1, 2, ‘g’, 5)
{} Создать словарь a = {‘x’: 6, ‘y’: 8}
x [a: b] Разрезать список х = [1, 3, 5, 6]
х [0: 2]

вывод: [1, 3]

x [ключ] Получить значение ключа в словаре x a = {‘x’: 6, ‘y’: 8}
печать (a [‘x’])

вывод: 6

x.append () Добавить список значений в пустой список х = [1]
x.append ([1,2,3])
печать (х)

вывод: [1, [1,2,3]]

x.extend () Добавить список значений для продолжения существующего списка без необходимости создания вложенного списка х = [1,2]
x.extend ([3,4,6,2])
печать (х)

выход:
[1, 2, 3, 4, 6, 2]

del (x [a: b]) Полностью удалить элемент из списка по определенному индексу х = [1,2,3,5]
del (x [0: 2])
печать (х)

вывод: [2,3,5]

del (x [ключ]) Полностью удалить ключ и значение из словаря по определенному индексу y = {1: 3, 2: 5, 4: 6, 8: 2}
del (y [1], y [8])
печать (у)

вывод = {2: 5, 4: 6}

dict.pop () Вытащить значение ключа и удалить его из словаря по определенному индексу а = {1: 3, 2: 4, 5: 6}
поп (1)

вывод: 3

dict.popetm () Вытащите последний элемент из словаря и удалите его а = {1: 2, 4: 8, 3: 5}
а.попьем ()

вывод: (3, 5)
печать (а)
вывод: {1: 2, 4: 8}

list.pop () Вытащить указанный индекс из списка и удалить его из списка a = [1, 3, 2, 4, 1, 6, 6, 4]
поп (-2)

вывод: 6
печать (а)
вывод: [1, 3, 2, 4, 1, 6, 4]

Чисто() Очистить элементы списка или словаря х = [1, 3, 5]
x.clear ()
печать (х)

выход: []

удалять() Удалить элемент из списка х = [1, 5, 6, 7]
x.remove (1)

вывод: [5, 6, 7]

вставить () Вставить элементы в список х = [3, 5, 6]
x.insert (1, 4)
печать (х)

вывод: [1, 4, 3, 5, 6]

сортировка (обратное = условие) Изменение направления элементов в списке на обратное х = [1, 3, 5, 6]
x.sort (обратный = True)
печать (х)

вывод: [6, 5, 3, 1]

Обновить() Обновите словарь, изменив его первый элемент и добавив в его конец любой другой элемент. х = {1: 3, 5: 6}
x.update ({1: 4, 8: 7, 4: 4})
печать (х)

вывод: {1: 4, 5: 6, 8: 7, 4: 4}

ключи () Показать все ключи в словаре а = {1: 2, 4: 8}
a.keys ()

вывод: dict_keys ([1, 4])

ценности() Показать все значения в словаре а = {1: 2, 4: 8}
a.values ​​()

вывод: dict_values ​​([2, 8])

Предметы() Отображение ключей и значений в словаре а = {1: 2, 4: 8}
a.items ()

вывод: dict_items ([(1, 2), (4, 8)])

получить (ключ) Получить значение элемента в словаре по его ключу а = {1: 2, 4: 8, 3: 5}
a.get (1)

вывод: 2

setdefault (ключ) Вернуть исходное значение элемента в словарь a.setdefault (2)
f = {** a, ** b} Объединить два словаря a = {‘x’: 6, ‘y’: 8}
b = {‘c’: 5, ‘d’: 3}
f = {** a, ** y}
печать (е)

вывод: {‘x’: 6, ‘y’: 8, ‘c’: 5, ‘d’: 3}

удалять() Удалите первое совпадающее значение элемента из списка, не обращая внимания на его индекс a = [1, 3, 2, 4, 4, 1, 6, 6, 4]
А. удалить (4)
печать (а)

вывод: [1, 3, 2, 4, 1, 6, 6, 4]

memoryview (x) Доступ к внутренним буферам объекта a = memoryview (объект)
байты () Преобразование протокола буфера памяти в байты байты (a [0: 2])
bytearray () Вернуть массив байтов bytearray (объект)
# Напишите одну строку комментария или запретите выполнение строки кода # Шпаргалка по регулярным выражениям Python
«» «» «» Напишите многострочный комментарий «» «Шпаргалка по регулярным выражениям Python подходит для начинающих
Это также отличное напоминание для экспертов «» «
Командная строка
пакет установки pip Установить онлайн-библиотеку pip install pandas
имя virtualenv Используйте virtaulenv для создания виртуальной среды virtualenv myproject
mkvirtualenv имя Используйте оболочку виртуальной среды для создания виртуальной среды mkvirtualenv myproject
python file.py Запустите команды в файле Python «python my_file.py
замораживание пипса Вывести список всех установленных пакетов в виртуальной среде замораживание пипса
pip freeze> somefiles Скопируйте все установленные библиотеки в один файл замораживание пипса> requirements.txt
где Найдите путь установки Python где питон
–версия Проверить версию пакета python –version
.исполняемый Запустите оболочку Python python.exe
с открытым (файл, ‘w’) Запись в существующий файл и перезапись его существующего содержимого с open (‘regex.txt’, ‘w’) как wf:
wf.write («Привет, мир!»)
с открытым (файл, ‘r’) Открыть файл только для чтения с open (‘regex.txt’, ‘r’) как rf:
печать (rf.read ()
с открытым (файл, ‘а’) Записать в файл без перезаписи существующего содержимого с open (‘regex.txt’, ‘a’) как af:
af.write (» nПривет, да!»)
file.close Закройте файл, если он не используется af = open (‘regex.txt’)
af.close
Выход Выйти из оболочки Python Выход()

Ростислав Дзинько: Регулярные выражения в Python: изучение и оптимизация


Writing a regular expression is more than a skill — it’s an art.

Jeffrey Friedl

Что это такое?

Рано или поздно практически каждому программисту в своей жизни приходится сталкиваться с регулярными выражениями.

Термин «Регулярные выражения» является переводом с английского словосочетания «Regular expressions» и есть не совсем точным, а для тех, кто первый раз услышал этот термин, наверное, даже сбивающем с толку (я, например, когда впервые услышал, никак не мог себе вообразить по названию, хотя бы даже примерно, что это, и для чего используется).

Литературный и более осмысленный перевод звучал бы, пожалуй, как «шаблонные выражения». Но название прижилось, а за «шаблонные выражения» вас попросту побьют :).

Отсюда:

Регулярное выражение

это cтрока, задающая шаблон поиска подстрок в тексте.

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

Где применяются регулярные выражения

Регулярные выражения имеют два основных направления применения:

  • анализ и поиск в текстовых массивах
  • проверка данных на соответствие шаблону

Область применения регулярных выражений очень широка. Вот несколько примеров:

  • анализ логов приложений
  • поиск и выборка информации из баз данных, организованных как простые текстовые файлы
  • URL Mapper’ы в веб-фреймворках (например, Django)
  • в приложениях для проверки правильности вводимой информации (например, телефона или адреса электронной почты).

Модуль re

В Python для работы с регулярными выражениями используется модуль re, который входит в стандартную библиотеку Python, начиная с версии Python 1.5. Его предшественник — модуль regex умер, а на Python 1.x сейчас уже, наверное, никто не пишет, так что про него забудьте.

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

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

Машина регулярных выражений в Python довольно медленная, поэтому может сильно затормозить работу ваших приложений. Поэтому, там, где это возможно, следует пользоваться другими, более подходящими под задачу, средствами. Например, для обработки html использовать регулярные выражения — не очень хорошая идея. Лучше воспользоваться html5lib или BeautifulSoup.

Вторым подводным камнем регулярных выражений есть сложность их прочтения для разработчиков с малым практическим опытом их применения, да и с большим тоже.test[0-9]*’ читать, как «найти текст, начиная с начала строки, который начинается словом test, после которого идет любое количество цифр». Такая интерпретация выражений очень помогает в понимании. Таким способом пользуюсь не только я, но его также рекомендует заслуженный деятель регулярных выражений Джефри Фридл, автор книги «Mastering Regular Expressions».

Средства модуля re для работы с регулярными выражениями

re.match(pattern, string)

Проверяет, соответствует ли начало строки «string» регулярному выражению «pattern». Например, выражению ‘test’ соответствует строка ‘test1’, но не соответствует строка ‘1test’. Возращает объект MatchObject, если строка найдена, или None, если не найдена. Обратите внимание, что также может быть найдена пустая строка, если она соответствует регулярному выражению.

re.search(pattern, string)

Работает аналогично re.match, но проверяет не только с начала строки, а сканирует строку на совпадения полностью. То есть, выражению ‘test’ будет соответствовать строка ‘1test’, в отличии от предыдущей функции. Зачем две функции? Очевидно, что если вас интересует только начало строки или строка в целом, нужно воспользоваться match, так как скорость его работы будет выше и она не будет делать лишнего сканирования

re.compile(pattern)

«Компилирует» регулярное выражение, заданное в качестве строки в объект для последующей работы. Используется для ускорения работы программы, если одно и то же регулярное выражение используется несколько раз. Например,

compiled_re = re.compile(‘test’)

compiled_re.match(‘test1’)

compiled_re.search(‘1test’)

Соответственно, все поисковые функции дублируются для скомпилированного объекта регулярного выражения, и выступают в качестве методов этого класса, которому стоит передавать единственным параметром анализируемую строку (флаги устанавливаются на этапе компиляции, но об этом немножко позже).

re.findall(pattern, string)

Выполняет поиск всех подстрок в строке, соответствующих регулярному выражению. Возвращает список найденных подстрок, строки не перекрываются.

re.finditer(pattern, string)

Работает так же, как и предыдущая функция, но возвращает итератор, состоящий из объектов MatchingObject.

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

Регулярные выражения на примерах

Итак, перейдем к объяснениям функций механизма регулярных выражений на примерах. Как показывает мой опыт, на примерах регулярные выражения усваиваются гораздо быстрее. Вместе с примерами буду, где это требуется подавать объяснения и «теоретический материал».

Для простоты разбора примеров будем рассматривать только строки, не содержащие символи перевода строки ‘\n’.

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

Задача №1: Поиск слова

Дано текст: This is a simple test message for test
Задача: Подсчитать количество слов test в строке.
Решение:


pattern = 'test'
string = 'This is a simple test message for test'
found = re.findall(pattern, string)
len(found) == string.count('test')

Задача №2: Поиск в начале и конце строки

Дано текст: This is a simple test message for test

Задача: Определить, заканчивается ли строка на слово test, и начинается ли на test. Определить является ли строка просто строкой test.

Теория:

Для того, чтобы обозначить конец строки используется символ $, а для обозначения начала строки — ^.test$’

re.search(pattern1, string) is None
False #Строка заканчивается на ‘test’

re.match(pattern2, string) is None
True #Строка не начинается на ‘test’

re.match(pattern3, string) is None
True #Строка не является строкой ‘test’

re.match(pattern3, string2) is None
False #Строка является строкой ‘test’


Задача №3: Поиск любого символа

Дано текст: We can get 300 to 540 time faster code if we add about 340 lines of code

Задача: Найти все трехзначные числа в тексте, которые начинаются на цифру 3 и заканчиваются на 0.

Теория:

Для того, чтобы указать, что в искомой строке может находится любой символ (кроме символа новой строки) нужно использовать точку — . . Чтобы учитывался и символ новой строки необходимо установить флаг (но об этом позже).

Решение:


string = 'We can get 300 to 540 time faster code if we add about 340 lines of code'
pattern = '3.0'
found = re.findall(pattern, string)
['300', '340']

Данное регулярное выражение ищет трехзначное число (на самом деле, не трехзначное число, а последовательность из трех символов, даже если они внутри более разрядного числа, первый из которых 3, последний — 0, а между ними — любой символ), но для данной строки и задачи пока достаточно.

Как видим, точка обозначает любой символ. Чтобы заставить регулярное выражение искать строчку ‘3.0’ достаточно поставить перед точкой обратный слеш — ‘3\.0’.

Задача №4: Поиск по группе символов

Дано текст: If 300 spartans were so brave, so 500 spartans could destroy more than 10k warriors of Darius, but 15k and even 20k.
Задача: Найти все цифры в тексте
Теория:

Для того, чтобы указать механизму искать конкретные символы, используются квадратные скобки — [ и ]. Например, [0-9] — все цифры, [a-z] — все буквы нижнего регистра, [123abc] — любой символ из этих шести символов.

Решение:


pattern = '[0-9]'
string = 'If 300 spartans were so brave, so 500 spartans could destroy more than 10k warriors of Darius, but 15k and even 20k'
set(re.findall(pattern, string))
set(['1', '0', '3', '2', '5'])

Задача №5: Поиск с повторениями

Дано текст: If 300 spartans were so brave, so 500 spartans could destroy more than 10k warriors of Darius, but 15k and even 20k.

Задача: Найти все числа в тексте
Теория:

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

* — предшествующее выражение может повторяться 0 или больше раз (то есть пустую строку также найдем)

+ — предшествующее выражение может повторяться 1 или больше раз (пустую стркоу не найдем)

? — предшествующее выражение может повторяться 0 или 1 раз (пустую строку найдем). Соответственно, если вопросительный отсутствует, выражение должно повториться 1 раз.

Решение:


pattern = '[0-9]+'
string = 'If 300 spartans were so brave, so 500 spartans could destroy more than 10k warriors of Darius, byt 15k and even 20k'
set(re.findall(pattern, string))
set(['300', '10', '15', '500', '20'])

Задача №6: Сокращенная запись последовательностей

Дано тексты:

The temperature can be in range 10-15C next week though it was lesser last week(4-9C). It was -5 some time ago.
The temperature can be in range 10- 15C next week though it was lesser last week(4 — 9C). It was even -5 some time ago.

Задача: Найти все диапазоны чисел в строке
Теория:

Для того, чтобы выделить диапазон нам потребуется указать символ дефиса — ‘-‘. Так как это управляющий символ, нам необходимо его экранировать, то есть использовать обратный слеш — ‘\’. Для часто используемых групп символов удобнее использовать сокращения для групп. Для цифр — это \d. Другие можно найти в документации.

Решение:


pattern1 = '[\d\-]+'
string1 = 'The temperature can be in range 10-15C next week though it was lesser last week(4-9C).'
re.findall(pattern1, string1)
['10-15', '4-9']

pattern2 = '[\d]+ *- *[\d]+'
string2 = 'The temperature can be in range 10- 15C next week though it was lesser last week(4 - 9C). It was even -5 some time ago'
re.findall(pattern2, string2)
['10- 15', '4 - 9']

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

  1. [\d]+ — сначала идет число
  2. |пробел|* — дальше может быть любое количество пробелов, а может и не быть
  3. — дефис
  4. |пробел|* — дальше может быть любое количество пробелов, а может и не быть
  5. [\d]+ — заканчивается искомая строка числом

Данная задача уже более практическая и приносящая пользу. Но, опять-таки, данное регулярное выражение имеет недостаток. Оно не учитывает отрицательные числа.

Примечание! Сокращенные записи для всех последовательностей можно узнать в документации к модулю re.

Задача № 7: Группировка результатов поиска на примере анализа лога

Дано: строки результата логирования команды ping в Ubuntu Linux.

log=[
'64 bytes from localhost.localdomain (127.0.0.1): icmp_req=1 ttl=64 time=0.033 ms',
'64 bytes from localhost.localdomain (127.0.0.1): icmp_req=2 ttl=64 time=0.034 ms',
'64 bytes from localhost.localdomain (127.0.0.1): icmp_req=3 ttl=64 time=0.031 ms',
'64 bytes from localhost.localdomain (127.0.0.1): icmp_req=4 ttl=64 time=0.031 ms']

Задача: найти пары «номер запроса» -> «время ответа»
Теория

Такой «сырой» лог трудно анализировать. Гораздо лучше то, что мы пытаемся получить в результате выполнения задачи. Естественно сырой лог будет одной строкой, но все же представим, что мы разбили его на отдельные строки. Для того, чтобы получить сгруппированные результаты можно воспользоваться круглыми скобками: ( и ). До этого мы пользовались findall, но MatchingObject имеет параметры group и groups, которые возвращают найденные результаты. groups возвращает кортеж групп результатов, group(number) возвращает результат для группы за номером number.

Если в строке есть несколько групп, которые соответствуют одному и тому же шаблону, не стоит его копировать в выражении несколько раз, достаточно сократить запись к номеру группы. То есть ([abc])([abc]) равнозначно ([abc])(\1). Кто знаком с конфигурацией mod_rewrite, например, в сервере Apache2, точно сталкивался с такой записью, так как там она применяется сплошь и рядом.

Решение:


import pprint
pattern = re.compile('(icmp_req=[\d]+).*(time=[\d\.]+ ms)')
result = []
for line in log:
    result.append(pattern.search(line).groups())
pprint.>]+>'
string = '<p>text<b>bold text</b>.<p>'
re.findall(pattern,string)
['<p>', '<b>', '</b>', '</p>']

Задача №9: Ограничение выдачи по длине или жадность регулярных выражений

Дано: список изделий, заданных строками в следующем виде

things = ['"Table" "1" "200$"',
          '"Stool" "2" "100$"',
          '"Mirror" "3" "400$"']

Задача: извлечь из списка параметры изделий
Теория:

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

Решение:


import pprint
pattern = re.compile('".*?"')
result = []
for line in things:
    result.append(pattern.findall(line))
pprint.pprint(result)
[['"Table"', '"1"', '"200$"'],
 ['"Stool"', '"2"', '"100$"'],
 ['"Mirror"', '"3"', '"400$"']]

Также данную задачу можно решить способом, описанным в предыдущем примере, применив следующее регулярное выражение: ‘«[^»]*»

Задача №10: Корекция выдачи по количеству повторений

Дано текст: 333334 333 123 2334 33345 54443 2195433333332 123333333 44444
Задача: Найти все последовательности цифер 3 в строке, длиной от 2 до 4-х символов.
Теория:

Для того, чтобы указать количество повторений последовательности в регулярных выражениях используются фигурные скобки — { и }. При этот можно задавать как диапазон повторений, так и фиксированное количество. Например, выражение ‘a{3}’ найдет все последовательности по 3 буквы ‘a’ подряд, а выражение ‘a{3,5}’ найдет все последовательности литер ‘a’ длиной от 3 до 5.

Решение:


pattern = '3{2,4}'
string = '333334 333 123 2334 33345 54443 2195433333332 123333333 44444'
re.findall(pattern, string)
['3333', '333', '33', '333', '3333', '333', '3333', '333']

Не очень-то практическая задачка, но, тем не менее демонстрирует контроль за количеством повторений последовательности символов.

Задача №11: Префиксные и постфиксные проверки

Дано текст: 333334 333 123 2334 33345 54443 2195433333332 123333333 44444
Задача: Найти все числа, в которых встречаются последовательности цифер 3 длиной от 2 до 4-х символов.
Теория:

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

(?<=<условие>)<выражение> — <выражение> будет соответствовать шаблону только тогда, когда оно идет после выражения, которое соответствует шаблону <условие>.

(?<!<условие>)<выражение> — аналогично предыдущему, только будет совпадать, если <условие> НЕ будет совпадать.

(?=<условие>)<выражение> — постфиксное условие, <выражение> будет соответстовать, если после него идет выражение, которое соответствует шаблону <условие>

(?!<условие>)<выражение> — постфиксное условие с отрицанием

Решение:


pattern = '[\d]*(?<!3)3{2,4}(?!3)[\d]*'
string = '333334 333 123 2334 33345 54443 2195433333332 123333333 44444'
re.findall(pattern, string)
['333', '2334', '33345']

Разберем составленное выражение:

  1. [d]* — идет любое количество цифер или цифер нет.
  2. (?<!3) — последующее выражение будет соответствовать только если оно не идет после цифры 3.
  3. 3{2,4} — последовательность цифер 3 длиной от 2-х до 4-х символов
  4. (?!3) — предыдущее выражение будет соответствовать только, когда после него не идет цифра 3.
  5. [d]* — идет любое количество цифер или цифер нет.

Задача №12: Операция «ИЛИ»

Дано текст: ruby python 456 java 789 j2not clash3win
Задача: Найти все упоминания языков программирования в строке.
Теория:

Для того, чтобы указать возможные последовательности символов в конкретном месте строки, в регулярных выражениях используется операция «ИЛИ», обозначается символом |.

Решение:


pattern = 'ruby|java|python|c#|fortran|c\+\+'
string = 'ruby python 456 java 789 j2not clash3win'
re.findall(pattern, string)
['ruby', 'python', 'java']

О примерах

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

Флаги

Я уже упоминал о флагах в начале статьи. Флаги используются для модификации поведения механизма поиска. Передаются третим параметром поисковой функции или вторым параметром при компиляции регулярного выражения. Есть следующие флаги:

  • re.DOTALL — символ «.» также учитывает переводы строки «\n», если этот флаг не установлен, то перевод строки не будет воспринят как «любой символ»
  • re.IGNORECASE — ищет строки без учета регистра символов, то есть символ ‘f’ и ‘F’ будут восприняты как одинаковые
  • re.’ будут ‘$’ учитывать только конец и начало строки, и не будут срабатывать на каждый перевод строки.
  • re.VERBOSE — включает игнорирование пробелов и переводов строки (кроме как при указании набора символов или если пробел указан с обратным слэшом) при создании регулярных выражений. Это позволяет делать регулярные выражения многострочными и добавлять комментарии после символа ‘#’.
  • re.UNICODE — делает сокращенные записи символьных последовательностей юникодовыми.

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

Внимание! Очевидная вещь — основой регулярных выражений являются сравнения строк. Соответственно, чем меньше сравнений производит машина, тем быстрее выполнится поиск. Назовем это «золотым правилом» регулярным выражений.

1. Вам это нужно?

Итак, сформулирую первую подсказку по оптимизации:

Определитесь, нужны ли вам регулярные выражения для данной задачи. Возможно, получится гораздо быстрее, если вы примените другой способ решения.

2. Операция «ИЛИ»

Эту операцию я не упоминал в примерах. Данная операция позволяет задавать условие соответствия. Задается символом |. Последовательность символов будет соответствовать шаблону если она соответствует или одной или другой части шаблона. Примеры:

pattern1 = 'word1|word2|word3|word4'
pattern2 = '[abc|cde]'
pattern3 = '(VeryLongcase|shortcase)'

Сейчас нас больше всего интересует шаблон pattern3. С точки зрения оптимизации скорости выполнения он записан неправильно. Обработка регулярных выражений в Python ведется слева направо, а условия работают в сокращенной форме, то есть если первое выполняется — второе просто не будет проверятся. Итак, мы вычислили первую подсказку:

При использовании операции | располагать части регулярного выражения слева направо следует в порядке возрастания времени проверки каждого из них.

3. Неопределенные повторения

Рассмотрим повторения. Чем больше повторений — тем больше сравнений. Еще одна проблема машины регулярных выражений Python — рекурсивный бектрекинг. Рекурсивный бектрекинг — это алгоритм определения совпадений. Недостатком его является то, что он попробует как можно больше вариантов поиска перед тем как сдаться, но он прост в реализации, поэтому довольно популярен. Поэтому:

Нужно избегать неопределенных повторений — *, +, лучше пользоваться фиксированными ограничителями: {from, to}.

4. Ограничение области поиска

Ограничение области видимости заключается в том, чтобы как можно более сузить область строки, в которой ведется поиска, то есть заставить поиск провалиться как можно раньше, и не делать лишних проверок. Поэтому, следует пользоваться операциями, которые ограничивают область поиска:

Всегда, где этого возможно, нужно как можно сильнее сузить область поиска., $, а также префиксные и постфиксные ограничители.

Также сузить область поиска поможет предварительная обработка текста. Зачастую текст можно урезать в несколько раз, таким образом искать по гораздо меньшей стоке.

5. Компиляция

Об этом уже говорилось, но для порядка сформулируем в отдельную подсказку:

Если вы используете одно и то же регулярное выражения в программе несколько раз — скомпилируйте его с помощью re.compile и используйте скомпилированный вариант для поиска.

6. Множественные выражения

Иногда бывает так, что более очевидным вариантом решения задачи кажется создания

нескольких, 2-х и больше выражений вместо одного. В этом случае следует помнить, что будет выполняться столько же поисковых проходов по тексту. Поэтому:

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

7. Избегайте вложенных выражений

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

Пример: Есть строка с ценой товара, в которой нужно произвести поиск. Такое регулярное выражение работает правильно: ‘\b.11.$’.

Поиск ведется следующим образом:

  1. Поиск ведется до нахождения начала слова. Фиксируется.
  2. Дальше ищем единички.
  3. Ищем знак доллара.
  4. Если знак доллара не найден, возвращаемся на шаг 2 и опять ищем единички.

Даже если нет такого, слова, которое заканчивается на $, поиск будет вестить до потери пульса, пока не будет выполнен перебор всех вариантов. Соответственно время выполнения будет вычисляться как длина строки, в которой ищем, умножить на количество двойных единичек, умножить на количество слов.\S*11\S$’ получим поиск с начала строки по символам, не содержащим пробел.

Следующая подсказка:

Избегайте вложенных циклов в регулярных выражениях.

В связи с этим еще одна подсказка:

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

8. Ищите только то, что вам нужно

Пример с тем ще злощасным \b. Нужно найти все слова в тексте. Можно написать так: ‘[\b\w]+’, но достаточно ‘[\w]+’.

Ищите только то, что нужно, и удаляйте лишнее из регулярных выражений.

9. Группируйте с умом

Механизм группировки очень медленная часть машины регулярных выражений. Поэтому:

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

Пример:

"(123|456)" - медленно
"123|456"- быстро

Регулярные выражения в Python 3 работают точно так же, как и в 2.х. Единственное отличие в том, что отсутствует флаг re.UNICODE, а вместо него добавлен флаг re.ASCII, чтобы производить ascii-only matching. Ну, Python 3 у нас ведь весь такой юникодовый из себя, так что почему так сделали, думаю, пояснения не требуются.

При отладке медленных регулярных выражений сильно помогает профилирование. Так что когда соврешенно неочевидно, что можно сделать, — следует запустить профайлер, и посмотреть все узкие места в коде. Особенно это важно при тестировании регулярных выражений. Старайтесь запускать профилирование на как можно больших строках, которые теоретически могут встретится в приложении. Из-за рекурсивной природы машины регулярных выражений в Python, на длинных строках можно получить самые неожиданные результаты, а оптимизация во многих случаях позволяет ускорить выполнение от нескольких часов до микросекунд. a…s $ ‘
test_string = ‘бездна’
результат = re.match (шаблон, тестовая_строка)

если результат:
print («Успешный поиск.»)
еще:
print («Поиск не увенчался успехом.»)

Здесь мы использовали функцию re.match () для поиска шаблона в test_string . Метод возвращает объект соответствия, если поиск успешен. В противном случае возвращается Нет .


Есть несколько других функций, определенных в модуле re для работы с RegEx. $ * + ? {} () \ |


[] — Квадратные скобки

Квадратные скобки обозначают набор символов, которые вы хотите сопоставить.

Выражение Строка Совпадает?
[abc] а 1 матч
ac 2 совпадения
Привет, Джуд Нет совпадений
abc de ca 5 совпадений

Здесь [abc] будет соответствовать, если строка, которую вы пытаетесь сопоставить, содержит любое из a , b или c . используется для проверки, начинается ли строка с определенного символа.ab abc 1 матч акб Нет совпадений (начинается с a , но не сопровождается b )


$ Доллар

Символ доллара $ используется для проверки, заканчивается ли строка определенным символом .

Выражение Строка Совпадает?
a $ а 1 матч
формула 1 матч
кабина Нет совпадений

* Звездочка

Звездочка * соответствует нулю или более вхождений оставшегося образца.

Выражение Строка Совпадает?
ма * н млн 1 матч
человек 1 матч
maaan 1 матч
основной Нет совпадений ( за не следует n )
женщина 1 матч

+ Плюс

Символ «плюс» + соответствует одному или нескольким вхождениям шаблона слева от него.

Выражение Строка Совпадает?
ма + н млн Не совпадает (нет - символ )
человек 1 матч
maaan 1 матч
основной Нет совпадений (за a не следует n)
женщина 1 матч

? Вопросительный знак

Знак вопроса ? соответствует нулю или одному вхождению оставшегося образца.

Выражение Строка Совпадает?
ма? Н млн 1 матч
человек 1 матч
maaan Нет совпадений (более одного символа )
основной Нет совпадений (за a не следует n)
женщина 1 матч

{} Раскосы

Рассмотрим этот код: {n, m} .Это означает, что ему осталось не менее n и не более m повторений шаблона.

Выражение Строка Совпадает?
а {2,3} abc dat Нет совпадений
abc daat 1 совпадение (при d aa t )
aabc daaat 2 совпадения (на aa bc и d aaa t )
aabc daaaat 2 совпадения (при aa bc и d aaa при )

Попробуем еще один пример.Это RegEx [0-9] {2, 4} соответствует минимум 2 цифрам, но не более 4 цифрам

Выражение Строка Совпадает?
[0-9] {2,4} ab123csde 1 совпадение (совпадение в ab 123 csde )
12 и 345673 3 совпадения ( 12 , 3456 , 73 )
1 и 2 Нет совпадений

| Чередование

Вертикальная полоса | используется для чередования (оператор или ).

Выражение Строка Совпадает?
a | b код Нет совпадений
аде 1 совпадение (совпадение по номеру a de )
acdbea 3 совпадения (на a cd b e a )

Здесь a | b соответствует любой строке, содержащей a или b


() Группа

Круглые скобки () используются для группировки подшаблонов.Например, (a | b | c) xz соответствует любой строке, которая соответствует a или b или c , за которым следует xz

Выражение Строка Совпадает?
(a | b | c) xz ab xz Нет совпадений
abxz 1 совпадение (совпадение на a bxz )
axz cabxz 2 совпадения (на axz bc ca bxz )

\ Обратная косая черта

Люфт \ используется для экранирования различных символов, включая все метасимволы.Например,

\ $ соответствует , если строка содержит $ , за которым следует - . Здесь $ не интерпретируется механизмом RegEx особым образом.

Если вы не уверены, имеет ли символ особое значение, вы можете поставить перед ним \ . Это гарантирует, что к персонажу не относятся по-особенному.


Особые последовательности

Специальные последовательности упрощают написание часто используемых шаблонов.Вот список специальных последовательностей:

\ A — соответствует, если указанные символы находятся в начале строки.

Выражение Строка Совпадает?
\ Athe солнце Матч
На солнце Нет совпадений

\ b — соответствует, если указанные символы находятся в начале или в конце слова.

Выражение Строка Совпадает?
\ bfoo футбол Матч
футбольный мяч Матч
Футбольный мяч Нет совпадений
фоо \ б Foo Матч
тест afoo Матч
самый быстрый Нет совпадений

\ B — Напротив \ b .Соответствует указанным символам , а не в начале или конце слова.

Выражение Строка Совпадает?
\ Bfoo футбол Нет совпадений
футбольный мяч Нет совпадений
Футбольный мяч Матч
foo \ B Foo Нет совпадений
тест afoo Нет совпадений
самый быстрый Матч

\ d — соответствует любой десятичной цифре. 0-9]

Выражение Строка Совпадает?
\ D 1ab34 "50 3 совпадения (при 1 ab 34 " 50 )
1345 Нет совпадений

\ s — соответствует, где строка содержит любой пробельный символ.Эквивалент [\ t \ n \ r \ f \ v] .

Выражение Строка Совпадает?
\ с Python RegEx 1 матч
PythonRegEx Нет совпадений

\ S — соответствует, где строка содержит любой непробельный символ. \ t \ n \ r \ f \ v] .

Выражение Строка Совпадает?
\ S а б 2 совпадения (на a b )
Нет совпадений

\ w — соответствует любому буквенно-цифровому символу (цифрам и алфавитам). Эквивалент [a-zA-Z0-9_] .Кстати, подчеркивание _ тоже считается буквенно-цифровым символом.

Выражение Строка Совпадает?
\ w 12 & ":; c 3 совпадения (на 12 & ":; c )
% ">! Нет совпадений

\ W — соответствует любому не буквенно-цифровому символу.a-zA-Z0-9_]

Выражение Строка Совпадает?
\ W 1a2% c 1 совпадение (на 1 a 2 % c )
Python Нет совпадений

\ Z — соответствует, если указанные символы находятся в конце строки.

Выражение Строка Совпадает?
Python \ Z Мне нравится Python 1 матч
Мне нравится программирование на Python Нет совпадений
Python - это весело. Нет совпадений

Совет: Для создания и тестирования регулярных выражений вы можете использовать инструменты тестера RegEx, такие как regex101. Этот инструмент не только помогает вам создавать регулярные выражения, но и помогает вам их изучить.

Теперь вы понимаете основы RegEx, давайте обсудим, как использовать RegEx в вашем коде Python.


Python RegEx

Python имеет модуль с именем re для работы с регулярными выражениями.Чтобы использовать его, нам нужно импортировать модуль.

  импорт по  

Модуль определяет несколько функций и констант для работы с RegEx.


re.findall ()

Метод re.findall () возвращает список строк, содержащих все совпадения.


Пример 1: re.findall ()

 
# Программа для извлечения чисел из строки

импорт ре

строка = 'привет 12 привет 89. Привет 34'
шаблон = '\ d +'

результат = re.findall (шаблон, строка)
печать (результат)

# Вывод: ['12', '89', '34']
  

Если шаблон не найден, re.findall () возвращает пустой список.


re.split ()

Метод re.split разбивает строку, в которой есть совпадение, и возвращает список строк, в которых произошло разбиение.


Пример 2: re.split ()

 
импорт ре

string = 'Двенадцать: 12 Восемьдесят девять: 89.'
шаблон = '\ d +'

результат = re.split (шаблон, строка)
печать (результат)

# Вывод: ['Двенадцать:', 'Восемьдесят девять:', '.']
  

Если шаблон не найден, re.split () возвращает список, содержащий исходную строку.


Вы можете передать аргумент maxsplit методу re.split () . Это максимальное количество разбиений, которое может произойти.

 
импорт ре

string = 'Двенадцать: 12 Восемьдесят девять: 89 Девять: 9.'
шаблон = '\ d +'

# maxsplit = 1
# разделить только при первом вхождении
результат = re.split (шаблон, строка, 1)
печать (результат)

# Вывод: ['Двенадцать:', 'Восемьдесят девять: 89 Девять: 9.']
  

Кстати, значение по умолчанию maxsplit равно 0; имея в виду все возможные расколы.


re.sub ()

Синтаксис re.sub () :

  re.sub (шаблон, замена, строка)  

Метод возвращает строку, в которой совпавшие вхождения заменяются содержимым переменной replace .


Пример 3: re.sub ()

 
# Программа для удаления всех пробелов
импорт ре

# многострочная строка
строка = 'abc 12 \
de 23 \ n f45 6 '

# соответствует всем пробельным символам
шаблон = '\ s +'

# пустой строкой
заменить = ''

new_string = re.sub (шаблон, замена, строка)
печать (новая_строка)

# Вывод: abc12de23f456
  

Если шаблон не найден, re.sub () возвращает исходную строку.


Вы можете передать count в качестве четвертого параметра методу re.sub () . Если опущено, результат будет 0. Это заменит все вхождения.

 
импорт ре

# многострочная строка
строка = 'abc 12 \
de 23 \ n f45 6 '

# соответствует всем пробельным символам
шаблон = '\ s +'
заменить = ''

new_string = re.sub (r '\ s +', заменить, строка, 1)
печать (новая_строка)

# Выход:
# abc12de 23
# f45 6
  

re.subn ()

re.subn () аналогичен re.sub () , за исключением того, что он возвращает кортеж из 2 элементов, содержащий новую строку и количество сделанных замен.


Пример 4: re.subn ()

 
# Программа для удаления всех пробелов
импорт ре

# многострочная строка
строка = 'abc 12 \
de 23 \ n f45 6 '

# соответствует всем пробельным символам
шаблон = '\ s +'

# пустой строкой
заменить = ''

new_string = re.subn (шаблон, заменить, строка)
печать (новая_строка)

# Вывод: ('abc12de23f456', 4)
  

re.search ()

Метод re.search () принимает два аргумента: шаблон и строку. Метод ищет первое место, где шаблон RegEx соответствует строке.

Если поиск успешен, re.search () возвращает соответствующий объект; в противном случае возвращается Нет .

  match = re.search (шаблон, строка)  

Пример 5: re.поиск ()

 
импорт ре

string = "Python - это весело"

# проверяем, стоит ли Python в начале
match = re.search ('\ APython', строка)

если совпадение:
  print ("шаблон найден внутри строки")
еще:
  print («шаблон не найден»)

# Вывод: образец найден внутри строки
  

Здесь match содержит объект соответствия.


Сопоставить объект

Вы можете получить методы и атрибуты объекта соответствия с помощью функции dir ().

Некоторые из наиболее часто используемых методов и атрибутов объектов сопоставления:


матч.группа ()

Метод group () возвращает часть строки, в которой есть совпадение.

Пример 6: Сопоставить объект

 
импорт ре

строка = '39801 356, 2102 1111'

# Трехзначное число, за которым следует пробел, за которым следует двузначное число
шаблон = '(\ d {3}) (\ d {2})'

# Переменная соответствия содержит объект Match.
match = re.search (шаблон, строка)

если совпадение:
  печать (match.group ())
еще:
  print («шаблон не найден»)

# Вывод: 801 35
  

Здесь match переменная содержит объект соответствия.

Наш шаблон (\ d {3}) (\ d {2}) имеет две подгруппы (\ d {3}) и (\ d {2}) . Вы можете получить часть строки этих подгрупп в скобках. Вот как:

  >>> match.group (1)
'801'

>>> match.group (2)
'35'
>>> match.group (1, 2)
('801', '35')

>>> match.groups ()
('801', '35')
  

match.start (), match.end () и match.span ()

Функция start () возвращает индекс начала сопоставленной подстроки.Точно так же end () возвращает конечный индекс совпавшей подстроки.

  >>> match.start ()
2
>>> match.end ()
8  

Функция span () возвращает кортеж, содержащий начальный и конечный индексы совпадающей части.

  >>> match.span ()
(2, 8)  

match.re и match.string

Атрибут re сопоставленного объекта возвращает объект регулярного выражения. Точно так же строка атрибут возвращает переданную строку.

  >>> match.re
re.compile ('(\\ d {3}) (\\ d {2})')

>>> match.string
'39801 356, 2102 1111'
  

Мы рассмотрели все часто используемые методы, определенные в модуле re . Если вы хотите узнать больше, посетите модуль Python 3 re.


Использование префикса r перед RegEx

Если перед регулярным выражением используется префикс r или R , это означает необработанную строку. Например, '\ n' — это новая строка, тогда как r '\ n' означает два символа: обратная косая черта \ , за которой следует n .

Люфт \ используется для экранирования различных символов, включая все метасимволы. Однако использование префикса r делает \ нормальным символом.


Пример 7: Необработанная строка с префиксом r

 
импорт ре

string = '\ n и \ r - escape-последовательности.'

result = re.findall (r '[\ n \ r]', строка)
печать (результат)

# Вывод: ['\ n', '\ r']
  

Регулярные выражения в Python (часть 1) — Real Python

Большинство функций в модуле re принимают необязательный аргумент .Сюда входит функция, с которой вы теперь очень хорошо знакомы, re.search () .

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

Поддерживаемые флаги регулярных выражений

В таблице ниже кратко перечислены доступные флаги. Все флаги, кроме re.DEBUG , имеют короткое однобуквенное имя, а также более длинное полное имя:

Краткое имя Длинное имя Эффект
р.Я re.IGNORECASE Выполняет сопоставление буквенных символов без учета регистра
re.M re.MULTILINE Заставляет привязки начала и конца строки соответствовать встроенным символам новой строки
re.S re.DOTALL Заставляет метасимвол точки соответствовать новой строке
re.X рэ.VERBOSE Позволяет включать пробелы и комментарии в регулярное выражение.
---- re.DEBUG Заставляет синтаксический анализатор регулярных выражений отображать отладочную информацию на консоли
re.A re.ASCII Задает кодировку ASCII для классификации символов
re.U re.UNICODE Задает кодировку Unicode для классификации символов
р.L повторно МЕСТНЫЙ Задает кодировку для классификации символов на основе текущей локали.

В следующих разделах более подробно описано, как эти флаги влияют на поведение сопоставления.

re.I
re.IGNORECASE

Делает совпадение нечувствительным к регистру.

Когда действует IGNORECASE , при сопоставлении символов регистр не учитывается:

>>>

  1 >>> re.поиск ('а +', 'аааааа')
 2 <_sre.SRE_Match объект; span = (0, 3), match = 'aaa'>
 3 >>> re.search ('A +', 'aaaAAA')
 4 <_sre.SRE_Match объект; span = (3, 6), match = 'AAA'>
 5
 6 >>> re.search ('a +', 'aaaAAA', re.I)
 7 <_sre.SRE_Match объект; span = (0, 6), match = 'aaaAAA'>
 8 >>> re.search ('A +', 'aaaAAA', re.IGNORECASE)
 9 <_sre.SRE_Match объект; span = (0, 6), match = 'aaaAAA'>
  

При поиске в строке 1 , a + соответствует только первым трем символам 'aaaAAA' .Точно так же в строке 3 , A + соответствует только последним трем символам. Но при последующих поисках синтаксический анализатор игнорирует регистр, поэтому и a + , и A + соответствуют всей строке.

IGNORECASE влияет на алфавитное сопоставление, включая классы символов:

>>>

  >>> re.search ('[a-z] +', 'aBcDeF')
<_sre.SRE_Match объект; span = (0, 1), match = 'a'>
>>> re.search ('[a-z] +', 'aBcDeF', re.Я)
<_sre.SRE_Match объект; промежуток = (0, 6), совпадение = 'aBcDeF'>
  

Если регистр имеет значение, самая длинная часть 'aBcDeF' , которой соответствует [a-z] + , является просто начальным 'a' . Указание re.I делает поиск нечувствительным к регистру, поэтому [a-z] + соответствует всей строке.

re.M
re.MULTILINE

Заставляет привязки начала и конца строки совпадать во встроенных символах новой строки.база, с))
Никто

>>> print (re.search (‘foo $’, s))
Никто
>>> print (re.search (‘bar $’, s))
Никто
>>> re.search (‘baz $’, s)
<_sre.SRE_Match объект; span = (8, 11), match = 'baz'>

В этом случае, даже если строка поиска 'foo \ nbar \ nbaz' содержит встроенные символы новой строки, только 'foo' соответствует при привязке в начале строки и только 'baz' соответствует при привязке в конце. foo’, s, re.baz ‘, s, re.MULTILINE)
<_sre.SRE_Match объект; span = (8, 11), match = 'baz'>

>>> re.search (‘foo $’, s, re.M)
<_sre.SRE_Match объект; промежуток = (0, 3), совпадение = 'foo'>
>>> re.search (‘bar $’, s, re.M)
<_sre.SRE_Match объект; span = (4, 7), match = 'bar'>
>>> re.search (‘baz $’, s, re.M)
<_sre.SRE_Match объект; span = (8, 11), match = 'baz'>

В строке 'foo \ nbar \ nbaz' все три из 'foo' , 'bar' и 'baz' встречаются либо в начале, либо в конце строки, либо в начале или конец строки внутри строки.Якоря и $ диктуют, что «стержень» должен находиться в начале и в конце строки. Указание флага MULTILINE делает эти совпадения успешными.

В примерах строк 8 и 10 вместо них используются флаги \ A и \ Z . Вы можете видеть, что эти совпадения завершаются неудачно даже при установленном флаге MULTILINE .

re.S
re.DOTALL

вызывает точку (.) для соответствия новой строке.

Помните, что по умолчанию метасимвол точка соответствует любому символу, кроме символа новой строки. Флаг DOTALL снимает это ограничение:

>>>

  1 >>> print (re.search ('foo.bar', 'foo \ nbar'))
 2 Нет
 3 >>> re.search ('foo.bar', 'foo \ nbar', re.DOTALL)
 4 <_sre.SRE_Match объект; span = (0, 7), match = 'foo \ nbar'>
 5 >>> re.search ('foo.bar', 'foo \ nbar', re.S)
 6 <_sre.Объект SRE_Match; span = (0, 7), match = 'foo \ nbar'>
  

В этом примере в строке 1 метасимвол точка не соответствует новой строке в 'foo \ nbar' . На строках 3 и 5 действует , DOTALL , поэтому точка соответствует новой строке. Обратите внимание, что краткое имя флага DOTALL re.S , а не re.D , как вы могли ожидать.

re.X
re.VERBOSE

Позволяет включать пробелы и комментарии в регулярное выражение.

Флаг VERBOSE определяет несколько особых действий:

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

  • Если регулярное выражение содержит символ # , который не содержится в классе символов или экранирован обратной косой чертой, то синтаксический анализатор игнорирует его и все символы справа от него.

Какая от этого польза? Он позволяет отформатировать регулярное выражение в Python, чтобы оно было более читабельным и самодокументированным.

Вот пример, показывающий, как это можно использовать. Предположим, вы хотите проанализировать телефонные номера в следующем формате:

  • Дополнительный трехзначный код города в скобках
  • Необязательный пробел
  • Трехзначный префикс
  • Разделитель ( - или . (\ (\ d {3} \))? \ S * \ d {3} [-.# Начало строки
    ... (\ (\ d {3} \))? # Необязательный код города
    ... \ s * # Необязательный пробел
    ... \ d {3} # Трехзначный префикс
    ... [-.] # Символ-разделитель
    ... \ d {4} # Четырехзначный номер строки
    ... $ # Якорь в конце строки
    ... '' '

    >>> re.search (регулярное выражение, '414.9229', re.VERBOSE)
    <_sre.SRE_Match объект; span = (0, 8), match = '414.9229'>
    >>> ре.поиск (регулярное выражение, '414-9229', re.VERBOSE)
    <_sre.SRE_Match объект; span = (0, 8), match = '414-9229'>
    >>> re.search (регулярное выражение, '(712) 414-9229', re.X)
    <_sre.SRE_Match объект; span = (0, 13), match = '(712) 414-9229'>
    >>> re.search (регулярное выражение, '(712) 414-9229', re.X)
    <_sre.SRE_Match объект; span = (0, 14), match = '(712) 414-9229'>

    Вызов re.search () аналогичен показанным выше, поэтому вы можете видеть, что это регулярное выражение работает так же, как указанное ранее.Но на первый взгляд это не так сложно понять.

    Обратите внимание, что тройные кавычки делают особенно удобным включение встроенных символов новой строки, которые квалифицируются как игнорируемые пробелы в режиме VERBOSE .

    При использовании флага VERBOSE помните о пробелах, которые, по вашему мнению, должны быть значимыми. Рассмотрим эти примеры:

    >>>

      1 >>> re.search ('foo bar', 'foo bar')
     2 <_sre.SRE_Match объект; span = (0, 7), match = 'foo bar'>
     3
     4 >>> печать (re.search ('foo bar', 'foo bar', re.VERBOSE))
     5 Нет
     6
     7 >>> re.search ('foo \ bar', 'foo bar', re.VERBOSE)
     8 <_sre.SRE_Match объект; span = (0, 7), match = 'foo bar'>
     9 >>> re.search ('foo [] bar', 'foo bar', re.VERBOSE)
    10 <_sre.SRE_Match объект; span = (0, 7), match = 'foo bar'>
      

    После всего, что вы видели к этому моменту, вам может быть интересно, почему в строке , строка 4 , регулярное выражение foo bar не соответствует строке 'foo bar' . Это не так, потому что флаг VERBOSE заставляет синтаксический анализатор игнорировать пробел.

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

    Как и флаг DOTALL , обратите внимание, что флаг VERBOSE имеет неинтуитивно понятное короткое имя: re.X , а не re.V .

    re.DEBUG

    Отображает отладочную информацию.

    Флаг DEBUG заставляет синтаксический анализатор регулярных выражений в Python отображать отладочную информацию о процессе синтаксического анализа на консоли:

    >>>

      >>> re.поиск ('foo.bar', 'fooxbar', re.DEBUG)
    ЛИТЕРАЛЬНЫЙ 102
    ЛИТЕРАЛЬНЫЙ 111
    ЛИТЕРАЛЬНЫЙ 111
    ЛЮБОЙ Нет
    ЛИТЕРАЛЬНЫЙ 98
    ЛИТЕРАЛЬНЫЙ 97
    ЛИТЕРАЛЬНЫЙ 114
    <_sre.SRE_Match объект; span = (0, 7), match = 'fooxbar'>
      

    Когда синтаксический анализатор отображает LITERAL nnn в выводе отладки, он показывает код ASCII буквального символа в регулярном выражении. В данном случае буквенные символы: 'f' , 'o' , 'o' и 'b' , 'a' , 'r' .

    Вот более сложный пример.(\ (\ d {3} \))? \ s * \ d {3} [-.] \ d {4} $ ‘

    >>> re.search (регулярное выражение, ‘414.9229’, re.DEBUG)
    В AT_BEGINNING
    MAX_REPEAT 0 1
    ПОДРАЗДЕЛЕНИЕ 1 0 0
    ЛИТЕРАЛЬНЫЙ 40
    MAX_REPEAT 3 3
    В
    CATEGORY CATEGORY_DIGIT
    ЛИТЕРАЛЬНЫЙ 41
    MAX_REPEAT 0 MAXREPEAT
    В
    CATEGORY CATEGORY_SPACE
    MAX_REPEAT 3 3
    В
    CATEGORY CATEGORY_DIGIT
    В
    ЛИТЕРАЛЬНЫЙ 45
    ЛИТЕРАЛЬНЫЙ 46
    MAX_REPEAT 4 4
    В
    CATEGORY CATEGORY_DIGIT
    В AT_END
    <_sre.SRE_Match объект; span = (0, 8), match = '414.9229'>

    Похоже, это много эзотерической информации, которая вам никогда не понадобится, но может быть полезна.См. «Глубокое погружение» ниже для практического применения.

    Deep Dive: отладка синтаксического анализа регулярных выражений

    Как вы знаете из вышеизложенного, последовательность метасимволов {m, n} указывает определенное количество повторений. Он соответствует где угодно от м до n повторений того, что ему предшествует:

    >>>

      >>> re.search ('x [123] {2,4} y', 'x222y')
    <_sre.SRE_Match объект; промежуток = (0, 5), совпадение = 'x222y'>
      

    Вы можете проверить это с помощью флага DEBUG :

    >>>

      >>> re.search ('x [123] {2,4} y', 'x222y', re.DEBUG)
    ЛИТЕРАЛЬНЫЙ 120
    MAX_REPEAT 2 4
      В
        ЛИТЕРАЛЬНЫЙ 49
        ЛИТЕРАЛЬНЫЙ 50
        ЛИТЕРАЛЬНЫЙ 51
    ЛИТЕРАЛЬНЫЙ 121
    <_sre.SRE_Match объект; промежуток = (0, 5), совпадение = 'x222y'>
      

    MAX_REPEAT 2 4 подтверждает, что синтаксический анализатор регулярных выражений распознает последовательность метасимволов {2,4} и интерпретирует ее как квантор диапазона.

    Но, как отмечалось ранее, если пара фигурных скобок в регулярном выражении в Python содержит что-либо, кроме допустимого числа или числового диапазона, тогда оно теряет свое особое значение.

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

    >>>

      >>> re.search ('x [123] {foo} y', 'x222y', re.DEBUG)
    ЛИТЕРАЛЬНЫЙ 120
    В
      ЛИТЕРАЛЬНЫЙ 49
      ЛИТЕРАЛЬНЫЙ 50
      ЛИТЕРАЛЬНЫЙ 51
    ЛИТЕРАЛЬНЫЙ 123
    ЛИТЕРАЛЬНЫЙ 102
    ЛИТЕРАЛЬНЫЙ 111
    ЛИТЕРАЛЬНЫЙ 111
    ЛИТЕРАЛЬНЫЙ 125
    ЛИТЕРАЛЬНЫЙ 121
      

    Вы можете видеть, что в выходных данных отладки нет токена MAX_REPEAT . Лексемы LITERAL указывают, что синтаксический анализатор обрабатывает {foo} буквально, а не как последовательность метасимволов квантора. 123 , 102 , 111 , 111 и 125 — это коды ASCII для символов в литеральной строке '{foo}' .

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

    Любопытно, что модуль re не определяет однобуквенную версию флага DEBUG . Вы можете определить свое собственное, если хотите:

    >>>

      >>> импорт
    >>> ре.D
    Отслеживание (последний вызов последний):
      Файл "", строка 1, в 
    AttributeError: модуль re не имеет атрибута D
    
    >>> re.D = re.DEBUG
    >>> re.search ('фу', 'фу', re.D)
    ЛИТЕРАЛЬНЫЙ 102
    ЛИТЕРАЛЬНЫЙ 111
    ЛИТЕРАЛЬНЫЙ 111
    <_sre.SRE_Match объект; промежуток = (0, 3), совпадение = 'foo'>
      

    Но это может скорее сбить с толку, чем помочь, поскольку читатели вашего кода могут неверно истолковать его как аббревиатуру для флага DOTALL . Если вы все же выполнили это задание, было бы неплохо его тщательно задокументировать.

    re.A
    re.ASCII
    re.U
    re.UNICODE
    re.L
    re.LOCALE

    Укажите кодировку символов, используемую для анализа специальных классов символов регулярных выражений.

    Для нескольких последовательностей метасимволов регулярных выражений ( \ w , \ W , \ b , \ B , \ d , \ D , \ s и \ S ) требуется вы можете назначать символы определенным классам, таким как слово, цифра или пробел.Флаги в этой группе определяют схему кодирования, используемую для присвоения символов этим классам. Возможные кодировки: ASCII, Unicode или в соответствии с текущим языковым стандартом.

    У вас было краткое введение в кодировку символов и Unicode в учебнике по строкам и символьным данным в Python при обсуждении встроенной функции ord () . Для получения более подробной информации посетите эти ресурсы:

    Почему кодировка символов так важна в контексте регулярных выражений в Python? Вот небольшой пример.

    Ранее вы узнали, что \ d определяет однозначный символ. В описании последовательности метасимволов \ d указано, что она эквивалентна классу символов [0-9] . Это верно для английского и западноевропейских языков, но для большинства языков мира символы от '0' до '9' не представляют все или даже любых цифр.

    Например, вот строка, состоящая из трех цифр деванагари:

    >>>

      >>> s = '\ u0967 \ u096a \ u096c'
    >>> с
    '१४६'
      

    Чтобы синтаксический анализатор регулярных выражений правильно учитывал сценарий Деванагари, последовательность метасимволов цифр \ d также должна соответствовать каждому из этих символов.

    Консорциум Unicode создал Unicode для решения этой проблемы. Юникод — это стандарт кодировки символов, разработанный для представления всех мировых систем письма. Все строки в Python 3, включая регулярные выражения, по умолчанию являются Unicode.

    Итак, вернемся к перечисленным выше флагам. Эти флаги помогают определить, попадает ли символ в данный класс, указав, какая кодировка используется: ASCII, Unicode или текущая локаль:

    • re.U и re.UNICODE указывает кодировку Unicode. По умолчанию используется Unicode, поэтому эти флаги излишни. В основном они поддерживаются для обратной совместимости.
    • re.A и re.ASCII принудительно определяют на основе кодирования ASCII. Если вы работаете на английском языке, это все равно происходит, поэтому флаг не повлияет на то, будет ли найдено совпадение.
    • re.L и re.LOCALE делают определение на основе текущего языкового стандарта.Локаль — устаревшее понятие и не считается надежным. За исключением редких случаев, она вам вряд ли понадобится.

    Используя кодировку Unicode по умолчанию, синтаксический анализатор регулярных выражений должен уметь обрабатывать любой язык, который вы ему задаете. В следующем примере он правильно распознает каждый из символов в строке '१४६' как цифру:

    >>>

      >>> s = '\ u0967 \ u096a \ u096c'
    >>> с
    '१४६'
    >>> re.search ('\ d +', s)
    <_sre.Объект SRE_Match; промежуток = (0, 3), совпадение = '१४६'>
      

    Вот еще один пример, показывающий, как кодировка символов может повлиять на соответствие регулярному выражению в Python. Рассмотрим эту строку:

    >>>

      >>> s = 'sch \ u00f6n'
    >>> с
    'schön'
      

    'schön' (немецкое слово pretty или nice ) содержит символ 'ö' , который имеет 16-битное шестнадцатеричное значение Unicode 00f6 . Этот символ не может быть представлен в традиционном 7-битном ASCII.

    Если вы работаете на немецком языке, вы должны разумно ожидать, что синтаксический анализатор регулярных выражений будет рассматривать все символы в 'schön' как символы слова. Но посмотрите, что произойдет, если вы выполните поиск символов слова s с использованием класса символов \ w и принудительно установите кодировку ASCII:

    >>>

      >>> re.search ('\ w +', s, re.ASCII)
    <_sre.SRE_Match объект; промежуток = (0, 3), совпадение = 'sch'>
      

    Когда вы ограничиваете кодировку ASCII, синтаксический анализатор регулярных выражений распознает только первые три символа как символы слова.Матч заканчивается на 'ö' .

    С другой стороны, если вы укажете re.UNICODE или разрешите кодировку по умолчанию на Unicode, тогда все символы в 'schön' квалифицируются как символы слова:

    >>>

      >>> re.search ('\ w +', s, re.UNICODE)
    <_sre.SRE_Match объект; промежуток = (0, 5), совпадение = 'schön'>
    >>> re.search ('\ w +', s)
    <_sre.SRE_Match объект; промежуток = (0, 5), совпадение = 'schön'>
      

    Флаги ASCII и LOCALE доступны на случай, если они понадобятся вам в особых обстоятельствах.bar ‘,’ FOO \ nBAR \ nBAZ ‘, re.I | re.M)
    <_sre.SRE_Match объект; span = (4, 7), match = 'BAR'>

    В этом вызове re.search () используется побитовое ИЛИ для одновременного указания флагов IGNORECASE и MULTILINE .

    Установка и сброс флагов в регулярном выражении

    Помимо возможности передавать аргумент в большинство вызовов функций модуля re , вы также можете изменять значения флагов в регулярном выражении в Python.Есть две последовательности метасимволов регулярных выражений, которые обеспечивают эту возможность.

    (? )

    Устанавливает значение флага на время регулярного выражения.

    В регулярном выражении последовательность метасимволов (? ) устанавливает указанные флаги для всего выражения.

    Значение — это одна или несколько букв из набора a , i , L , m , s , u и x .Вот как они соответствуют флагам модуля re :

    Письмо Флаги
    а re.A re.ASCII
    i re.I re.IGNORECASE
    л re.L re.LOCALE
    м рэ.M re.MULTILINE
    с re.S re.DOTALL
    u re.U re.UNICODE
    x re.X re.VERBOSE

    Последовательность метасимволов (? ) в целом соответствует пустой строке. Он всегда соответствует успешно и не использует строку поиска.bar ‘,’ FOO \ nBAR \ nBAZ \ n ‘)
    <_sre.SRE_Match объект; span = (4, 7), match = 'BAR'>

    Обратите внимание, что последовательность метасимволов (? ) устанавливает данный флаг (ы) для всего регулярного выражения, независимо от того, где вы поместите его в выражение:

    >>>

      >>> re.search ('foo.bar (? S) .baz', 'foo \ nbar \ nbaz')
    <_sre.SRE_Match объект; span = (0, 11), match = 'foo \ nbar \ nbaz'>
    
    >>> re.search ('foo.bar.baz (? s)', 'foo \ nbar \ nbaz')
    <_sre.SRE_Match объект; span = (0, 11), match = 'foo \ nbar \ nbaz'>
      

    В приведенных выше примерах оба метасимвола точки соответствуют символам новой строки, потому что действует флаг DOTALL .Это верно, даже когда (? S) появляется в середине или в конце выражения.

    Начиная с Python 3.7, указывать (? ) в любом месте регулярного выражения, кроме начала, не рекомендуется:

    >>>

      >>> import sys
    >>> sys.version
    '3.8.0 (по умолчанию, 14 октября 2019 г., 21:29:03) \ n [GCC 7.4.0]'
    
    >>> re.search ('foo.bar.baz (? s)', 'foo \ nbar \ nbaz')
    : 1: DeprecationWarning: флаги не в начале
        выражения 'foo.bar.baz (? s) '
    <объект re.Match; span = (0, 11), match = 'foo \ nbar \ nbaz'>
      

    Соответствующее совпадение по-прежнему будет найдено, но вы получите предупреждающее сообщение.

    (? - : )

    Устанавливает или удаляет значение флага на время действия группы.

    (? - : ) определяет группу без захвата, которая соответствует .Для , содержащегося в группе, синтаксический анализатор регулярных выражений устанавливает любые флаги, указанные в , и сбрасывает все флаги, указанные в .

    Значения для и чаще всего равны i , m , s или x .

    В следующем примере для указанной группы установлен флаг IGNORECASE :

    >>>

      >>> re.search ('(? i: foo) bar', 'FOObar')
    <объект re.Match; span = (0, 6), match = 'FOObar'>
      

    Это дает совпадение, потому что (? I: foo) диктует, что совпадение с 'FOO' нечувствительно к регистру.

    Теперь сравните это с этим примером:

    >>>

      >>> print (re.search ('(? I: foo) bar', 'FOOBAR'))
    Никто
      

    Как и в предыдущем примере, совпадение с 'FOO' будет успешным, поскольку оно нечувствительно к регистру.Но после выхода из группы IGNORECASE больше не действует, поэтому сопоставление с 'BAR' чувствительно к регистру и не выполняется.

    Вот пример, демонстрирующий отключение флага для группы:

    >>>

      >>> print (re.search ('(? - i: foo) bar', 'FOOBAR', re.IGNORECASE))
    Никто
      

    Опять нет совпадений. Хотя re.IGNORECASE обеспечивает сопоставление без учета регистра для всего вызова, последовательность метасимволов (? -I: foo) отключает IGNORECASE на время этой группы, поэтому сопоставление с 'FOO' не удается .

    Начиная с Python 3.7, вы можете указать u , a или L как , чтобы переопределить кодировку по умолчанию для указанной группы:

    >>>

      >>> s = 'sch \ u00f6n'
    >>> с
    'schön'
    
    >>> # Требуется Python 3.7 или новее
    >>> re.search ('(? a: \ w +)', s)
    <объект re.Match; промежуток = (0, 3), совпадение = 'sch'>
    >>> re.search ('(? u: \ w +)', s)
    <объект re.Match; промежуток = (0, 5), совпадение = 'schön'>
      

    Однако вы можете установить кодировку только таким образом.Вы не можете удалить его:

    >>>

      >>> re.search ('(? - a: \ w +)', s)
    Отслеживание (последний вызов последний):
      Файл "", строка 1, в 
      Файл "/usr/lib/python3.8/re.py", строка 199, в поиске
        return _compile (шаблон, флаги) .search (строка)
      Файл "/usr/lib/python3.8/re.py", строка 302, в _compile
        p = sre_compile.compile (шаблон, флаги)
      Файл "/usr/lib/python3.8/sre_compile.py", строка 764, в компиляции
        p = sre_parse.parse (p, флаги)
      Файл "/ usr / lib / python3.8 / sre_parse.py ", строка 948, в синтаксическом анализе
        p = _parse_sub (источник, состояние, флаги и SRE_FLAG_VERBOSE, 0)
      Файл "/usr/lib/python3.8/sre_parse.py", строка 443, в _parse_sub
        itemsappend (_parse (источник, состояние, подробный, вложенный + 1,
      Файл "/usr/lib/python3.8/sre_parse.py", строка 805, в _parse
        flags = _parse_flags (источник, состояние, символ)
      Файл "/usr/lib/python3.8/sre_parse.py", строка 904, в _parse_flags
        поднять source.error (msg)
    re.error: плохие встроенные флаги: невозможно отключить флаги 'a', 'u' и 'L' в
    позиция 4
      

    u , a и L являются взаимоисключающими.В группе может быть только один из них. a-c6] соответствует любому символу, кроме «a», «b», «c» или «6». R | S соответствует регулярному выражению R или регулярному выражению S () создает группу захвата и указывает приоритет

    Квантификаторы

    * 0 или больше (добавьте ? для нежадных)
    + 1 или более (добавьте ? для нежадных)
    ? 0 или 1 (добавьте ? для нежадных)
    {m} ровно м м находок
    {m, n} с м до n . м по умолчанию 0, n до бесконечности
    {м, п}? от м до n , как можно меньше

    Специальные последовательности

    \ A начало строки
    \ б соответствует пустой строке на границе слова (между \ w и \ W )
    \ B соответствует пустой строке не на границе слова
    \ d цифра
    \ D нецифровый
    \ с пробелов: [\ t \ n \ r \ f \ v]
    \ S без пробелов
    \ w буквенно-цифровой: [0-9a-zA-Z_]
    \ Вт без букв и цифр
    \ Z конец строки
    \ g соответствует ранее определенной группе

    Специальные последовательности

    Утверждение упреждающего просмотра

    Утверждение

    (? ILmsux) соответствует пустой строке, устанавливает re.X флаги
    (?: ...) Версия обычных круглых скобок без захвата
    (? P ...) соответствует тому, что соответствовало ранее названной группе
    (? P =) цифра
    (? # ...) комментарий; игнорируется
    (? =...) : соответствует без использования
    (?! ...) утверждение отрицательного просмотра вперед
    (? <= ...) просмотра назад: соответствует, если предшествует
    (? утверждение отрицательного просмотра назад
    (? (Id) да | нет) соответствует "да", если группа "id" совпадает, иначе "нет"

    Регулярное выражение в Python с примерами | Набор 1

    Модуль регулярных выражений (RE) определяет набор строк (шаблон), который ему соответствует.Соответствует началу
    $ Соответствует концу
    . Соответствует любому символу, кроме новой строки
    ? Соответствует нулю или одному вхождению.
    | Означает ИЛИ (соответствует любому из символов
    разделенные им.
    * Любое количество вхождений (включая 0 вхождений)
    + Одно или несколько вхождений
    {} Укажите количество вхождений предыдущего RE
    чтобы соответствовать.
    () Вложить группу RE

    • Функция compile ()
      Регулярные выражения компилируются в объекты шаблонов, которые имеют методы для различных операций, таких как поиск совпадений с шаблоном или выполнение подстановок строк.

    Питон

    импорт re

    р = р. собрать ( '[a-e]' )

    print (p.findall ( "Да, сказал г-н Гибенсон Старк" ))

    Выход:

     ['e', 'a', 'd', 'b', 'e', ​​'a']
    
    
    
     

    Общие сведения о выводе:
    Первое появление - это «e» в «Да», а не «A», поскольку оно чувствительно к регистру.
    Next Occurrence - это «a» в «сказанном», затем «d» в «сказанном», за которым следуют «b» и «e» в «Гибенсоне». Последний «a» соответствует слову «Старк».
    Метасимвол обратная косая черта «\» играет очень важную роль, поскольку сигнализирует о различных последовательностях. Если обратная косая черта должна использоваться без специального значения в качестве метасимвола, используйте ’\\’

     \ d Соответствует любой десятичной цифре, это эквивалентно
         к заданному классу [0-9].
    \ D Соответствует любому нецифровому символу.
    \ s Соответствует любому пробельному символу.
    \ S Соответствует любому непробельному символу
    \ w Соответствует любому буквенно-цифровому символу, это
         эквивалент класса [a-zA-Z0-9_].\ W Соответствует любому не буквенно-цифровому символу.
    
    
     

    Установить класс [\ s ,.] будет соответствовать любому пробельному символу, ‘,’ или, ’.’.

    Питон

    импорт re

    р = р. собрать ( '\ d' )

    print (p.findall ( "Я пошел к нему в 11 А.М. 4 июля 1886 г. " ))

    р = р. собрать ( '\ d +' )

    print (p.findall ( «Я пошел к нему в 11 часов утра 4 июля 1886 года» ))

    Вывод:

     ['1', '1', '4', '1', '8', '8', '6']
    ['11', '4', '1886']
    
    
    
     

    Питон

    импорт re

    р = р. собрать ( '\ w' )

    print (p.findall ( "Он сказал * на some_lang." ))

    р = р. собрать ( '\ w +' )

    print (p.findall ( "Я пошел к нему в 11 утра, он сказал *** на каком-то языке." ))

    р = р. собрать ( '\ W' )

    print (p.findall ( "он сказал *** на some_language." ))

    Выход:

     ['H', 'e', ​​'s', 'a', 'i', 'd', 'i', 'n', 's', 'o', 'm', 'e', '_', 'l', 'a', 'n', 'g']
    ['Я', 'пошел', 'к', 'ему', 'в', '11', 'А', 'М', 'он', 'сказал', 'в', 'some_language']
    ['', '', '*', '*', '*', '', '', '.']
    
    
     

    Питон

    импорт re

    р = р. собрать ( 'ab *' )

    печать (p.findall ( "ababbaabbb" ))

    Выход:

     ['ab', 'abb', 'a', 'abbb']
    
    
     

    Понимание вывода:
    Наш RE - это ab *, где «a» сопровождается любым номером.of «b’s», начиная с 0.
    Выход «ab» действителен, так как одиночный «a» сопровождается одиночным «b».
    Выход «abb» действителен, так как одиночный «a» сопровождается двумя «b».
    Выход «a» действителен, поскольку одиночный «a» сопровождается 0 «b».
    Выход «abbb», действителен, потому что одиночный «a» сопровождается 3 «b».

    • Функция split ()
      Разбивает строку по вхождениям символа или шаблона, при нахождении этого шаблона оставшиеся символы из строки возвращаются как часть результирующего списка.
      Синтаксис:
     re.split (шаблон, строка, maxsplit = 0, flags = 0)
    
    
     

    Первый параметр, pattern обозначает регулярное выражение, string - это заданная строка, в которой будет выполняться поиск шаблона и в которой происходит разделение, maxsplit, если он не указан, считается равным нулю '0', и если предоставлено любое ненулевое значение, тогда происходит самое большее количество расщеплений. Если maxsplit = 1, то строка будет разделена только один раз, в результате чего получится список длиной 2.Флаги очень полезны и могут помочь сократить код, они не являются необходимыми параметрами, например: flags = re.IGNORECASE. В этом разбиении регистр будет проигнорирован.

    Питон

    из повторно импорт сплит

    печать (разделить ( '\ W +' , 'Слова, слова, слова' ))

    печать (разделить ( '\ W +' , "Word's words Words" ))

    печать (разделение ( '\ W +' , '12 января 2016 г., 11:02' ))

    печать (разделение ( '\ d +' , '12 января 2016 г., 11:02' ))

    Выход:

     ["слова", "слова", "слова"]
    ['Word', 's', 'слова', 'слова']
    ['On', '12th', 'Jan', '2016', 'at', '11', '02', 'AM']
    ['On', 'th Jan', ', at', ':', 'AM']
    
    
     

    Питон

    импорт re

    печать (re.split ( '\ d +' , '12 января 2016 г., в 11:02' , 1 ))

    print (re.split ( '[a-f] +' , 'Aey, Boy oh boy, come here' , flags = re.IGNORECASE))

    print (re.split ( '[a-f] +' , 'Эй, мальчик ой, иди сюда' ))

    Выход:

     ['On', января 2016 г., 11:02]
    ['', 'y,', 'oy oh', 'oy,', 'om', 'h', 'r', '']
    ['A', 'y, Boy oh', 'oy,', 'om', 'h', 'r', '']
    
    
     
     рэ.sub (шаблон, repl, строка, count = 0, flags = 0)
    
    
     

    'sub' в функции означает SubString, определенный шаблон регулярного выражения ищется в данной строке (3-й параметр), и при нахождении шаблона подстроки заменяется на repl (2-й параметр), count проверяет и поддерживает количество раз это происходит.

    Питон

    импорт re

    печать (re.sub ( 'ub' , '~ *' , 'Субъект уже забронировал Uber' , flags = re.IGNORECASE))

    print (re.sub ( 'ub' , '~ *' , 'Субъект уже забронировал Uber' ))

    print (re.sub ( 'ub' , '~ *' , 'Субъект уже забронировал Uber' , count = 1 , flags = рэ.IGNORECASE))

    print (re.sub (r '\ sAND \ s' , '&' , 'Baked Beans And Spam' , flags = re.IGNORECASE ))

    Выход

     S ~ * объект уже забронирован
    S ~ * ject уже забронировал номер через Uber
    S ~ * ject уже забронировал номер через Uber
    Запеченная фасоль и спам
    
    
    
     
     рэ.subn (шаблон, repl, строка, count = 0, flags = 0)
    
    
     

    subn () похож на sub () во всех отношениях, за исключением способа предоставления вывода. Он возвращает кортеж с общим количеством замен и новую строку, а не только строку.

    Питон

    импорт re

    print (re.subn ( 'ub' , '~ *' , 'Субъект уже забронировал Uber' ))

    т = рэ.subn ( 'ub' , '~ *' , 'Субъект уже зарезервировал Uber' , flags = re.IGNORECASE)

    печать (т)

    печать ( лен (t))

    печать (т [ 0 ])

    Выход

     ('S ~ * ject уже забронировал Uber', 1)
    ('S ~ * объект уже ~ * забронирован', 2)
    Длина кортежа: 2
    С ~ * объект уже забронирован
    
    
     
    • Функция escape ()
      Синтаксис:
     рэ.escape (строка)
    
    
     

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

    Питон

    импорт re

    print (re.escape ( «Это ужасно даже в час ночи» ))

    печать (re.Вау

    Статья по теме:
    https://www.geeksforgeeks.org/regular-expressions-python-set-1-search-match-find/
    Ссылка:
    https://docs.python.org/2 /library/re.html

    Эта статья предоставлена ​​ Piyush Doorwar . Если вам нравится GeeksforGeeks, и вы хотели бы внести свой вклад, вы также можете написать статью на сайте deposit.geeksforgeeks.org или отправить свою статью по почте @ geeksforgeeks.орг. Посмотрите, как ваша статья появляется на главной странице GeeksforGeeks, и помогите другим гикам.
    Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или если вы хотите поделиться дополнительной информацией по теме, обсуждаемой выше.

    Внимание компьютерщик! Укрепите свои основы с помощью курса Python Programming Foundation и изучите основы.

    Для начала подготовьтесь к собеседованию. Расширьте свои концепции структур данных с помощью курса Python DS .

    Модуль

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

    Python - это язык сценариев высокого уровня с открытым исходным кодом. Встроенный в Python модуль «re» обеспечивает отличную поддержку регулярных выражений с современным и полным вкусом регулярных выражений. Единственные важные функции, отсутствующие в синтаксисе регулярных выражений Python, - это атомарная группировка, притяжательные квантификаторы и свойства Unicode.

    Первое, что нужно сделать, это импортировать модуль regexp в ваш скрипт с помощью import re.

    Regex Search and Match

    Call re. поиск (регулярное выражение, тема), чтобы применить шаблон регулярного выражения к строке темы. Функция возвращает None, если попытка сопоставления не удалась, и объект Match в противном случае. Поскольку None оценивается как False, вы можете легко использовать re.search () в операторе if. В объекте Match хранятся сведения о части строки, совпадающей с шаблоном регулярного выражения.

    Вы можете установить режимы сопоставления регулярных выражений, указав специальную константу в качестве третьего параметра для re.a "," abc ", re.I | re.M).

    По умолчанию механизм регулярных выражений Python считает только буквы от A до Z, цифры от 0 до 9 и подчеркивание как" символы слова ". Укажите флаг re.L или re.LOCALE, чтобы \ w соответствовал всем символам, которые считаются буквами с учетом текущих настроек локали. Кроме того, вы можете указать re.U или re.UNICODE, чтобы обрабатывать все буквы из всех скриптов как символы слова. влияет на границы слов

    Не путайте re.search () с re. соответствует (). Обе функции делают то же самое, с тем важным отличием, что re.search () будет пытаться использовать шаблон по всей строке, пока не найдет совпадение. re.match (), с другой стороны, пытается использовать шаблон только в самом начале строки. По сути, re.match ("регулярное выражение", тема) совпадает с re.search ("\ Aregex", субъект). Обратите внимание, что re.match () , а не требует, чтобы регулярное выражение соответствовало всей строке. re.match («a», «ab») будет успешным.

    Python 3.4 добавляет новую версию re. функция fullmatch (). Эта функция возвращает объект Match, только если регулярное выражение полностью соответствует строке. В противном случае возвращается None. re.fullmatch ("регулярное выражение", тема) то же самое, что и re.search ("\ Aregex \ Z", тема). Это полезно для проверки ввода данных пользователем. Если subject - пустая строка, тогда fullmatch () оценивает True для любого регулярного выражения, которое может найти совпадение нулевой длины.

    Чтобы получить все совпадения из строки, вызовите re. findall (регулярное выражение, тема). Это вернет массив всех неперекрывающихся совпадений регулярных выражений в строке.«Неперекрывающиеся» означает, что строка просматривается слева направо, и следующая попытка совпадения начинается после предыдущего совпадения. Если регулярное выражение содержит одну или несколько групп захвата, re.findall () возвращает массив кортежей, причем каждый кортеж содержит текст, соответствующий всем группам захвата. Общее совпадение регулярного выражения - , а не , включенное в кортеж, если вы не поместите все регулярное выражение в группу захвата.

    Более эффективен, чем re.findall (). finditer (регулярное выражение, тема).Он возвращает итератор, который позволяет вам перебирать совпадения регулярного выражения в строке темы: for m в re.finditer (regex, subject). Переменная цикла for m - это объект Match с деталями текущего совпадения.

    В отличие от re.search () и re.match (), re.findall () и re.finditer () не поддерживают необязательный третий параметр с флагами сопоставления регулярных выражений. Вместо этого вы можете использовать модификаторы глобального режима в начале регулярного выражения. Например. «(? I) regex» соответствует регистру регулярных выражений без учета регистра.

    Строки, обратная косая черта и регулярные выражения

    Обратная косая черта - это метасимвол в регулярных выражениях, который используется для экранирования других метасимволов.Регулярное выражение \ соответствует одной обратной косой черте. \ d - это один токен, соответствующий цифре.

    В строках Python также используется обратная косая черта для экранирования символов. Вышеупомянутые регулярные выражения записываются как строки Python как «\\\\» и «\\ w». Действительно сбивает с толку.

    К счастью, в Python также есть «необработанные строки», которые не обрабатывают обратную косую черту. Как необработанные строки, вышеуказанные регулярные выражения становятся r "\\" и r "\ w". Единственным ограничением использования необработанных строк является то, что ограничитель, который вы используете для строки, не должен появляться в регулярном выражении, поскольку необработанные строки не предлагают средств для его выхода.

    Вы можете использовать \ n и \ t в необработанных строках. Хотя необработанные строки не поддерживают эти escape-последовательности, обработчик регулярных выражений поддерживает. Конечный результат такой же.

    Unicode

    До Python 3.3 модуль Python re не поддерживал токены регулярных выражений Unicode. Однако строки Python Unicode всегда поддерживали нотацию \ uFFFF. Модуль Python re может использовать строки Unicode. Таким образом, вы можете передать строку Unicode u "\ u00E0 \\ d" в модуль re, чтобы она соответствовала à, за которым следует цифра.Обратная косая черта для \ d была экранирована, а для \ u - нет. Это связано с тем, что \ d - это токен регулярного выражения, и необходимо экранировать обратную косую черту регулярного выражения. \ u00E0 - это строковый токен Python, который нельзя экранировать. Строка u "\ u00E0 \\ d" рассматривается обработчиком регулярных выражений как à \ d.

    Если вы поставили еще одну обратную косую черту перед \ u, обработчик регулярных выражений увидит \ u00E0 \ d. Если вы используете это регулярное выражение с Python 3.2 или более ранней версией, оно будет соответствовать буквальному тексту u00E0, за которым следует цифра.

    Чтобы избежать путаницы в том, нужно ли экранировать обратную косую черту, просто используйте необработанные строки Unicode, такие как ur "\ u00E0 \ d". Тогда обратную косую черту не нужно экранировать. Python интерпретирует escape-последовательности Unicode в необработанных строках.

    В Python 3.0 и более поздних версиях строки по умолчанию являются Unicode. Таким образом, префикс u, показанный в приведенных выше примерах, больше не нужен. Python 3.3 также добавляет поддержку нотации \ uFFFF в механизм регулярных выражений. Итак, в Python 3.3 вы можете использовать строку «\\ u00E0 \\ d» для передачи регулярного выражения \ u00E0 \ d, которое будет соответствовать чему-то вроде à0.

    Поиск и замена

    re. sub (регулярное выражение, замена, тема) выполняет поиск и замену по теме, заменяя все совпадения регулярного выражения в теме с заменой. Результат возвращается функцией sub (). Передаваемая вами строка темы не изменяется.

    Если регулярное выражение имеет группы захвата, вы можете использовать текст, совпадающий с частью регулярного выражения внутри группы захвата. Чтобы заменить текст из третьей группы, вставьте \ 3 в строку замены.Если вы хотите использовать текст третьей группы, за которым следует буквальная тройка, в качестве замены, используйте \ g <3> 3. \ 33 интерпретируется как 33-я группа. Будет ошибкой, если имеется менее 33 групп. Если вы использовали именованные группы захвата, вы можете использовать их в тексте замены с помощью \ g .

    Функция re.sub () применяет ту же логику обратной косой черты к тексту замены, что и к регулярному выражению. Следовательно, вы должны использовать необработанные строки для текста замены, как я это делал в приведенных выше примерах.Функция re.sub () также интерпретирует \ n и \ t в необработанных строках. Если вам нужна замена c: \ temp, используйте r "c: \\ temp" или "c: \\\\ temp". Третья обратная ссылка - r "\ 3" или "\\ 3".

    Разделение струн

    re. split (regex, subject) возвращает массив строк. Массив содержит части темы между всеми совпадениями регулярных выражений в теме. Смежные совпадения регулярных выражений приведут к появлению в массиве пустых строк. Сами совпадения регулярных выражений не включаются в массив.Если регулярное выражение содержит группы захвата, то текст, соответствующий группам захвата, включается в массив. Группы захвата вставляются между подстроками, которые появляются слева и справа от совпадения регулярного выражения. Если вам не нужны группы захвата в массиве, преобразуйте их в группы без захвата. Функция re.split () не предлагает опции для подавления захвата групп.

    Вы можете указать необязательный третий параметр, чтобы ограничить количество раз, когда строка темы разделяется.Обратите внимание, что этот предел контролирует количество разбиений, а не количество строк, которые окажутся в массиве. Неразделенный остаток объекта добавляется в качестве последней строки в массив. Если нет групп захвата, массив будет содержать элемент limit + 1.

    Поведение re.split () изменилось между версиями Python, когда регулярное выражение может находить совпадения нулевой длины. В Python 3.4 и ранее re.split () игнорирует совпадения нулевой длины. В Python 3.5 и 3.6 re.split () выдает FutureWarning, когда обнаруживает совпадение нулевой длины.Это предупреждение сигнализирует об изменении в Python 3.7. Теперь re.split () также разбивается на совпадения нулевой длины.

    Match Details

    re.search () и re.match () возвращают объект Match, а re.finditer () генерирует итератор для итерации по объекту Match. Этот объект содержит много полезной информации о совпадении регулярного выражения. Я буду использовать m для обозначения объекта Match в обсуждении ниже.

    г. группа () возвращает часть строки, совпадающую со всем регулярным выражением.м. start () возвращает смещение в строке начала совпадения. м. end () возвращает смещение символа за пределами совпадения. м. span () возвращает кортеж из двух m.start () и m.end (). Вы можете использовать m.start () и m.end (), чтобы разрезать строку темы: subject [m.start (): m.end ()].

    Если вы хотите получить результаты группы захвата, а не полное совпадение регулярного выражения, укажите имя или номер группы в качестве параметра. m.group (3) возвращает текст, соответствующий третьей группе захвата.m.group ('groupname') возвращает текст, соответствующий именованной группе 'groupname'. Если группа не участвовала в общем совпадении, m.group () возвращает пустую строку, а m.start () и m.end () возвращают -1.

    Если вы хотите выполнить поиск и замену на основе регулярного выражения без использования re.sub (), вызовите m. разверните (замена), чтобы вычислить текст замены. Функция возвращает заменяющую строку с замененными обратными ссылками и т. Д.

    Объекты регулярных выражений

    Если вы хотите использовать одно и то же регулярное выражение более одного раза, вы должны скомпилировать его в объект регулярного выражения.Объекты регулярных выражений более эффективны и делают ваш код более читабельным. Чтобы создать его, просто вызовите re. скомпилировать (регулярное выражение) или повторно. компилировать (регулярное выражение, флаги). Флаги - это параметры сопоставления, описанные выше для функций re.search () и re.match ().

    Объект регулярного выражения, возвращаемый re.compile (), предоставляет все функции, которые модуль re также предоставляет напрямую: search (), match (), findall (), finditer (), sub () и split (). Разница в том, что они используют шаблон, хранящийся в объекте регулярного выражения, и не принимают регулярное выражение в качестве первого параметра.re.compile (regex) .search (subject) эквивалентно re.search (regex, subject).

    Сделайте пожертвование

    Этот веб-сайт только что сэкономил вам поездку в книжный магазин? Сделайте пожертвование в поддержку этого сайта, и вы получите неограниченный доступ к этому сайту без рекламы!

    7 полезных приемов для изучения Python Regex | Кристофер Тао | Март, 2021

    Напишите с их помощью мощное и читаемое регулярное выражение

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

    В этой статье я собрал для вас 7 полезных советов по регулярному выражению в Python. Это либо маленькие уловки, которые могут повысить вашу продуктивность, решить некоторые сложные проблемы или улучшить читаемость кода. Надеюсь, они будут вам полезны!

    Фото PublicDomainPictures на Pixabay

    Многие ученики знают, что мы должны использовать «r-строку», когда мы определяем шаблон регулярного выражения.Однако я обнаружил, что многие люди не знают причины. Некоторые учащиеся думают о «r-строке» как о «строке регулярного выражения», что совершенно неверно. Вместо этого это должна быть «сырая строка».

    Как и другие языки программирования, Python имеет механизм «escape» в строках. Например, когда мы хотим иметь строку с кавычками, они должны быть экранированы, чтобы компилятор знал, что строка не должна заканчиваться, кавычки являются просто частью строки.

     s = 'I \' m Chris '

    Конечно, не только кавычки можно экранировать, есть много других сценариев, в которых мы должны использовать обратную косую черту.Например, \ n в следующей строке будет интерпретироваться как «новая строка».

     print ('a \ nb') 

    Если мы хотим иметь \ n как часть строки, другими словами, это не должна быть новая строка, мы можем использовать «r-строку» сказать Python не интерпретировать его.

     print (r'a \ nb ') 

    Когда мы пишем шаблон регулярного выражения, иногда нам приходится использовать косую черту или другие специальные символы. Следовательно, чтобы интерпретатор Python не интерпретировал строку неправильно.При определении шаблона регулярного выражения всегда рекомендуется использовать «r-строку».

    Предположим, мы ищем шаблон, в котором несколько букв повторяются после нескольких пробелов, мы можем написать регулярное выражение следующим образом.

     re.search (r '(\ w +) \ s + \ 1', 'abc abc') 

    Однако, если мы не будем использовать здесь «r-строку», индикатор «группа» \ 1 выиграет не узнавать.

    Фото Kadres на Pixabay

    «Флаги» - это своего рода уникальное явление в Python Regex, которого не было бы во всех других языках программирования.То есть создавать шаблоны регулярных выражений без учета регистра.

    Предположим, мы хотим сопоставить серию букв независимо от верхнего или нижнего регистра. Конечно, мы можем написать это так.

     re.search (r '[a-zA-Z] +', 'AbCdEfG') 

    Это определенно стандартный способ, и если мы не добавим AZ , он не будет соответствовать всей строке как и ожидалось.

    Однако Python предоставляет такой способ, что мы можем больше сосредоточиться на самом шаблоне и не беспокоиться о регистрах букв.То есть использовать re.IGNORECASE . Вы даже можете сделать его очень коротким, как re.I , который делает то же самое.

     re.search (r '[az] +', 'AbCdEfG', re.IGNORECASE) 
    re.search (r '[az] +', 'AbCdEfG', re.I)

    Фото StockSnap на Pixabay

    Одним из основных недостатков регулярного выражения является его плохая читаемость. Обычно это та составляющая, с которой нам приходится сталкиваться. Однако знаете ли вы, что в Python есть лучший способ улучшить читаемость строки шаблона регулярного выражения? То есть использовать re.Флаг VERBOSE .

    Мы можем переписать шаблон регулярного выражения в разделе 1. Первоначально строка шаблона должна быть r '(\ w +) \ s + \ 1' . Что ж, это неплохо, но предположим, что если у нас есть гораздо более сложный образец, вероятно, только автор может его понять. Это очень распространенная проблема с регулярным выражением. Однако с помощью подробного флага мы можем написать это так.

     re.search (r '' '
    (\ w +) # Группа 1: сопоставить одну или несколько букв, цифр или знак подчеркивания
    \ s + # Сопоставить один или несколько пробелов
    \ 1 # Сопоставить Группу 1 независимо от того, что это за
    ' '', 'abc abc', re.ГЛАГОЛЬНАЯ)

    Это в точности эквивалентно r '(\ w +) \ s + \ 1' . Обратите внимание, что флаг re.VERBOSE является обязательной вещью, если мы хотим написать его таким образом. В противном случае, конечно, регулярное выражение работать не будет.

    Опять же, у флага есть укороченная версия - re.X .

    Фото yongxinz на Pixabay

    re.sub () - одна из наиболее часто используемых функций в регулярных выражениях Python. Он пытается найти шаблон ( шаблон ) в строке ( строка ) и заменить его предоставленной строкой замены ( repl ).

    re.sub () - одна из наиболее часто используемых функций в регулярном выражении Python. Это

    re.sub (pattern, repl, string, count = 0, flags = 0)

    Например, следующий код скроет любые номера мобильных телефонов в строке.

     re.sub (r '\ d', '*', 'Мобильный номер пользователя - 1234567890') 

    Большинство разработчиков знают эту функцию до сих пор. Однако меньшее количество людей будет знать, что мы действительно можем использовать функцию для параметра repl .

    Например, мы по-прежнему хотим скрыть номер телефона пользователя, но хотим показать последние 3 цифры, чтобы убедиться, что пользователь понимает, что это за номер.Сначала мы можем определить следующую функцию.

     def hide_reserve_3 (s): 
    return '*' * (len (s [0]) - 3) + s [0] [- 3:]

    В этой функции требуется объект, соответствующий регулярному выражению Python ( s ) как единственный аргумент. Если есть несколько совпадений, объект s будет содержать несколько строк, поэтому нам нужно его зациклить. Но давайте рассмотрим этот пример просто для демонстрации. с [0] будет первым совпавшим телефонным номером.

    Затем мы вернули несколько раз повторяющиеся звездочки.То есть, если длина строки равна 10, то будет возвращено 10–3 = 7 звездочек. Затем последние 3 цифры будут сохранены как есть, поэтому они будут раскрыты.

    Конечно, лямбда-функция тоже будет работать. Если настроенная функция не слишком сложна, можно использовать лямбда-функцию.

     re.sub (r '\ d +', lambda s: '*' * (len (s [0]) - 3) + s [0] [- 3:], 'Мобильный номер пользователя - 1234567890 ') 

    Фото Shirley810 на Pixabay

    Иногда нам может понадобиться использовать узор несколько раз.Скорее всего, достаточно переменной r-string, которую можно использовать повторно. Однако, если мы хотим использовать шаблон для разных целей, а также хотим улучшить читаемость, использование re.compile () может быть лучшим выбором.

     pattern = re.compile ('abc') 

    После определения шаблона с помощью re.compile () , мы можем использовать его сколько угодно раз.

    Фото PDPics на Pixabay

    Иногда мы хотим использовать регулярное выражение для извлечения информации из строк, которые следуют тому же шаблону.Затем поместить их в словарь - неплохая идея. Например, строка «Меня зовут Кристофер Тао, и мне нравится Python». содержит имя, фамилию человека и предпочитаемый язык. Если у нас много такой строки и мы хотим извлечь информацию в словарь, мы действительно можем сделать это без каких-либо накладных расходов. Регулярное выражение Python может достичь этого прямо из коробки.

     re.match (
    r "Меня зовут (? P \ w +) (? P \ w +), и мне нравится (? P \ w +).",
    " Меня зовут Кристофер Тао, и мне нравится Python. "
    ) .groupdict ()

    В шаблоне регулярного выражения мы можем определить« ключ »совпадающей строки, и тогда они будут автоматически отображены в словарь .

    Мы должны следовать шаблону (? P ...) , где Y - имя ключа, ... - определенный шаблон регулярного выражения.

    Фото StockSnap на Pixabay

    Мы все Знайте, что регулярное выражение может улавливать шаблоны, однако иногда мы хотим уловить шаблоны более «продвинутым» способом.Например, мы не знаем, какой именно строке будет соответствовать шаблон, но мы хотим уловить все, если оно повторяется несколько раз.

    Фактически, пример, который мы использовали в разделах 1 и 3, как раз и достиг этого. Приведу еще один пример. То есть мы хотим узнать, есть ли в строке повторяющаяся буква. Если да, то что это?

     pair = re.compile (r '' '
    . * # Соответствует любому количеству любых символов
    (.) # Соответствует 1 символу, каким бы он ни был (кроме новой строки), это будет "группа 1"
    .* # Соответствует любому количеству любых символов
    \ 1 # Соответствует группе 1
    '' ', re.VERBOSE) pair.match (' abcdefgc '). Groups () [0]

    Нам нужно сначала определить шаблон. Здесь я использовал флаг re.VERBOSE , чтобы он был более читабельным и понятным. В шаблоне мы используем круглые скобки для определения «группы», а затем используем эту «группу» \ 1 позже, чтобы поймать «повторяющуюся» строку.

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

    Фото liming0759 на Pixabay

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

    Давайте вместе напишем Python Regex с большей удобочитаемостью. Жизнь коротка, используйте Python!

    Простое введение в Regex с Python | Тиртхаджоти Саркар

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

    Согласно этой статье, мировой рынок текстовой аналитики был оценен в 5,46 млрд долларов США в 2019 году и, как ожидается, достигнет 14,84 млрд долларов США к 2025 году.

    Источник изображения

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

    Поэтому начинающим специалистам по данным важно иметь предварительные знания об этом мощном инструменте для будущих проектов и аналитических задач.

    В Python есть встроенный модуль re , который необходимо импортировать для работы с Regex.

      import re  

    Это начальная точка страницы официальной документации .

    В этом коротком обзоре мы рассмотрим основы использования Regex в простой обработке текста с некоторыми практическими примерами на Python.

    Мы используем метод match , чтобы проверить, соответствует ли шаблон строке / последовательности. Это чувствительно к регистру.

    Вместо того, чтобы повторять код, мы можем использовать compile для создания программы с регулярным выражением и использования встроенных методов.

    Итак, скомпилированные программы возвращают специальный объект, например соответствуют объектам.Но если они не совпадают, он вернет Нет , и это означает, что мы все еще можем запустить наш условный цикл!

    Мы можем легко использовать дополнительные параметры в объекте match для проверки позиционного соответствия строкового шаблона.

    Выше мы заметили, что как только мы создали программу prog с шаблоном thon , мы можем использовать ее любое количество раз с различными строками.

    Также обратите внимание, что аргумент pos используется, чтобы указать, где следует искать соответствие.Для последних двух фрагментов кода мы меняем стартовую позицию и получаем разные результаты с точки зрения соответствия. хотя строка идентична.

    Давайте посмотрим на пример использования. Мы хотим узнать, сколько слов в списке имеют последние три буквы с «ing».

    Для решения указанной выше проблемы мы могли бы использовать простой строковый метод.

    Что такого сильного в регулярных выражениях?

    Ответ заключается в том, что он может соответствовать очень сложному шаблону. Но чтобы увидеть такие сложные примеры, давайте сначала рассмотрим метод поиска .

    Обратите внимание, как метод match возвращает None (потому что мы не указали правильную начальную позицию шаблона в тексте), но метод search находит позицию совпадения (путем сканирования текста) .

    Естественно, мы можем использовать метод span () объекта match , возвращенный search , чтобы определить положение совпадающего шаблона.

    Поиск эффективен, но он также ограничен поиском первого совпадения в тексте.Чтобы обнаружить все совпадения в длинном тексте, мы можем использовать методы findall и finditer .

    Метод findall возвращает список с совпадающим шаблоном. Вы можете подсчитать количество элементов, чтобы понять, как часто встречается искомый термин в тексте.

    Метод finditer создает итератор. Мы можем использовать это, чтобы увидеть дополнительную информацию, как показано ниже.

    Теперь мы осторожно выходим на арену, сквозь которую просвечивает Regex. Наиболее частое использование Regex связано с «сопоставлением с подстановочными знаками» или «нечетким сопоставлением».Здесь у вас есть не полный шаблон, а его часть, и вы все равно хотите найти, где в данном тексте появляется что-то похожее.

    Вот несколько примеров. Здесь мы также применим метод group () к объекту, возвращаемому search , чтобы по существу вернуть совпавшую строку.

    Односимвольное сопоставление с помощью DOT

    Точка . соответствует любому одиночному символу, кроме символа новой строки.

    Нижний регистр \ w для соответствия любой отдельной букве, цифре или знаку подчеркивания

    DOT ограничен алфавитными символами, поэтому нам нужно расширить репертуар с помощью других инструментов.

    (\ W или заглавная буква W) соответствует чему-либо, не покрытому \ w

    Есть символы, кроме буквы, цифр и подчеркивания. Мы используем \ W, чтобы поймать их.

    Сопоставление шаблонов с пробельными символами

    \ s (строчные буквы s) соответствует одному пробельному символу, например пробелу, новой строке, табуляции, возврату. Естественно, это используется для поиска шаблона с пробелом внутри него, например. пара слов.

    \ d соответствует числовым цифрам 0–9

    Вот пример.(каретка) соответствует шаблону в начале строки (но не где-либо еще).

    Конец строки

    Знак $ (знак доллара) соответствует шаблону в конце строки. Ниже приведен практический пример, в котором мы заинтересованы только в том, чтобы получить патентную информацию Apple и отказаться от данных других компаний. Мы проверяем конец текста на «Apple» и, только если он совпадает, извлекаем номер патента, используя числовой код сопоставления цифр, который мы показали ранее.

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

    Соответствует 0 или более повторений

    * соответствует 0 или более повторениям предыдущего регулярного выражения.

    Соответствие 1 или более повторений

    + заставляет результирующий RE соответствовать 1 или более повторениям предыдущего RE.

    Добавить комментарий

    Ваш адрес email не будет опубликован. Обязательные поля помечены *

    2024 © Все права защищены. Карта сайта