Рубрики
Без рубрики

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

Автор оригинала: Usman Malik.

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

Вступление

Предварительная обработка текста-одна из важнейших задач в обработке естественного языка (НЛП). Например, вы можете удалить все знаки препинания из текстовых документов, прежде чем их можно будет использовать для классификации текста. Аналогично, вы можете извлечь числа из текстовой строки. Написание ручных скриптов для таких задач предварительной обработки требует больших усилий и подвержено ошибкам. Принимая во внимание важность этих задач предварительной обработки, Регулярные выражения (aka Regex) были разработаны на разных языках, чтобы облегчить эти задачи предварительной обработки текста.

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

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

import re

Поиск шаблонов в строке

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

Для поиска шаблона в строке используется функция match и findall пакета re .

Функция соответствия

Инициализируйте переменную text текстовой строкой следующим образом:

text = "The film Titanic was released in 1998"

Давайте напишем регулярное выражение, которое соответствует строке любой длины и любому символу:

result = re.match(r".*", text)

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

Приведенное выше регулярное выражение будет соответствовать текстовой строке, так как мы пытаемся сопоставить строку любой длины и любого символа. Если совпадение найдено, функция match возвращает объект _sre.SRE_Match , как показано ниже:

type(result)

Выход:

_sre.SRE_Match

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

result.group(0)

Выход:

'The film Titanic was released in 1998'

В случае, если функция match не находит совпадения, возвращается объект null .

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

text = ""

Теперь, если вы снова выполните следующее регулярное выражение, совпадение будет найдено:

result = re.match(r".*", text)

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

Чтобы сопоставить строку длиной не менее 1, используется следующее регулярное выражение:

result = re.match(r".+", text)

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

Поиск по алфавиту

Функция match может использоваться для поиска любых букв алфавита в строке. Давайте инициализируем текстовую переменную следующим текстом:

text = "The film Titanic was released in 1998"

Теперь, чтобы найти все буквы алфавита, как прописные, так и строчные, мы можем использовать следующее регулярное выражение:

result = re.match(r"[a-zA-z]+", text)

Это регулярное выражение утверждает, что соответствует текстовой строке для любых алфавитов от small a до small z или capital A до capital Z . Знак плюс указывает, что строка должна содержать хотя бы один символ. Выведем совпадение, найденное по приведенному выше выражению:

print(result.group(0))

Выход:

The

В выходных данных вы можете видеть, что возвращается первое слово, т. е. The . Это происходит потому, что функция match возвращает только первое найденное совпадение. В регулярном выражении мы указали, что находим шаблоны как со строчными, так и с заглавными буквами от a до z . Первое найденное совпадение было The . После слова The есть пробел, который не рассматривается как буква алфавита, поэтому сопоставление остановилось и выражение вернуло только The , которое является первым совпадением.

Однако с этим есть проблема. Если строка начинается с числа вместо алфавита, функция match вернет null, даже если после числа есть алфавиты. Давайте посмотрим на это в действии:

text = "1998 was the year when the film titanic was released"
result = re.match(r"[a-zA-z]+", text)
type(result)

Выход:

NoneType

В приведенном выше скрипте мы обновили текстовую переменную, и теперь она начинается с цифры. Затем мы использовали функцию match для поиска алфавитов в строке. Хотя текстовая строка содержит алфавиты, null будет возвращен, так как функция match соответствует только первому элементу в строке.

Для решения этой задачи мы можем использовать функцию search .

Функция поиска

Функция search аналогична функции match , т. е. она пытается соответствовать указанному шаблону. Однако, в отличие от функции match , она соответствует шаблону глобально, а не только первому элементу. Таким образом, функция search вернет совпадение, даже если строка не содержит алфавита в начале строки, но содержит алфавит в другом месте строки, как показано ниже:

text = "1998 was the year when the film titanic was released"
result = re.search(r"[a-zA-z]+", text)
print(result.group(0))

Выход:

was

Функция search возвращает “was”, так как это первое совпадение, найденное в текстовой строке.

Совпадающая строка с самого начала

Чтобы проверить, начинается ли строка с определенного слова, вы можете использовать ключ моркови, т. е. ^ , за которым следует слово, соответствующее функции search , как показано ниже. Предположим, у нас есть следующая строка:

text = "XYZ 1998 was the year when the film titanic was released"

Если мы хотим узнать, начинается ли строка с “1998”, мы можем использовать функцию search следующим образом:

result = re.search(r"^1998", text)
type(result)

В выходных данных будет возвращен null , так как текстовая строка не содержит “1998” непосредственно в начале.

Теперь давайте изменим текстовую переменную content и добавим “1998” в начале, а затем проверим, найден ли “1998” в начале или нет. Выполните следующий сценарий:

text = "1998 was the year when the film titanic was released"
if re.search(r"^1998", text):
    print("Match found")
else:
    print("Match not found")

Выход:

Match found

Совпадающие строки с конца

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

text = "1998 was the year when the film titanic was released"
if re.search(r"1998$", text):
    print("Match found")
else:
    print("Match not found")

В приведенном выше сценарии мы попытались найти, заканчивается ли текстовая строка на “1998”, что не так.

Выход:

Match not found

Теперь, если мы обновим строку и добавим “1998” в конце текстовой строки, приведенный выше скрипт вернет “Совпадение найдено”, как показано ниже:

text = "was the year when the film titanic was released 1998"
if re.search(r"1998$", text):
    print("Match found")
else:
    print("Match not found")

Выход:

Match found

Подстановка текста в строку

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

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

text = "The film Pulp Fiction was released in year 1994"

Чтобы заменить строку “Криминальное чтиво” на “Форрест Гамп” (еще один фильм, вышедший в 1994 году), мы можем использовать функцию sub следующим образом:

result = re.sub(r"Pulp Fiction", "Forrest Gump", text)

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

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

Теперь давайте заменим все алфавиты в нашей строке символом “X”. Выполните следующий сценарий:

text = "The film Pulp Fiction was released in year 1994"
result = re.sub(r"[a-z]", "X", text)
print(result)

Выход:

TXX XXXX PXXX FXXXXXX XXX XXXXXXXX XX XXXX 1994

Из выходных данных видно, что все символы были заменены, кроме заглавных. Это происходит потому, что мы указали только a-z , а не A-Z . Есть два способа решить эту проблему. Вы можете указать A-Z в регулярном выражении вместе с a-z следующим образом:

result = re.sub(r"[a-zA-Z]", "X", text)

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

result = re.sub(r"[a-z]", "X", text, flags=re.I)

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

Классы сокращенных символов

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

Удаление цифр из строки

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

text = "The film Pulp Fiction was released in year 1994"
result = re.sub(r"\d", "", text)
print(result)

Выход:

The film Pulp Fiction was released in year 

Удаление букв алфавита из строки

text = "The film Pulp Fiction was released in year 1994"
result = re.sub(r"[a-z]", "", text, flags=re.I)
print(result)

Выход:

1994

Удаление символов Word

Если вы хотите удалить все символы слова (буквы и цифры) из строки и сохранить оставшиеся символы, вы можете использовать шаблон \w в вашем регулярном выражении и заменить его пустой строкой нулевой длины, как показано ниже:

text = "The film, '@Pulp Fiction' was ? released in % $ year 1994."
result = re.sub(r"\w","", text, flags = re.I)
print(result)

Выход:

, '@ '  ?   % $  .

Вывод показывает, что все цифры и алфавиты были удалены.

Удаление Несловесных символов

Чтобы удалить все несловесные символы, шаблон \W можно использовать следующим образом:

text = "The film, '@Pulp Fiction' was ? released in % $ year 1994."
result = re.sub(r"\W", "", text, flags=re.I)
print(result)

Выход:

ThefilmPulpFictionwasreleasedinyear1994

Из выходных данных вы можете видеть, что все было удалено (даже пробелы), кроме цифр и алфавитов.

Группировка Нескольких Паттернов

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

text = "The film, '@Pulp Fiction' was ? released _ in % $ year 1994."
result = re.sub(r"[,@\'?\.$%_]", "", text, flags=re.I)
print(result)

Выход:

The film Pulp Fiction was  released  in   year 1994

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

Удаление Нескольких Пробелов

Иногда несколько пробелов появляются между словами в результате удаления слов или знаков препинания. Например, в выходных данных последнего примера есть несколько пробелов между in и year . Эти пробелы могут быть удалены с помощью шаблона \s , который относится к одному пространству.

text = "The film      Pulp Fiction      was released in   year 1994."
result = re.sub(r"\s+"," ", text, flags = re.I)
print(result)

Выход:

The film Pulp Fiction was released in year 1994.

В приведенном выше сценарии мы использовали выражение \s+ , которое относится к одному или нескольким пробелам.

Удаление пробелов из начала и конца

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

text = "         The film Pulp Fiction was released in year 1994"
result = re.sub(r"^\s+", "", text)
print(result)

Выход:

The film Pulp Fiction was released in year 1994

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

text = "The film Pulp Fiction was released in year 1994      "
result = re.sub(r"\s+$", "", text)
print(result)

Удаление одного символа

Иногда удаление знаков препинания, таких как апостроф, приводит к одному символу, который не имеет никакого значения. Например, если вы удалите апостроф из слова Jacob's и замените его пробелом, результирующая строка будет Jacob s . Здесь s не имеет смысла. Такие одиночные символы могут быть удалены с помощью регулярного выражения, как показано ниже:

text = "The film Pulp Fiction     s was b released in year 1994"
result = re.sub(r"\s+[a-zA-Z]\s+", " ", text)
print(result)

Выход:

The film Pulp Fiction was released in year 1994

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

Разбиение строки

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

text = "The film      Pulp   Fiction was released in year 1994      "
result = re.split(r"\s+", text)
print(result)

Выход:

['The', 'film', 'Pulp', 'Fiction', 'was', 'released', 'in', 'year', '1994', '']

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

text = "The film, Pulp Fiction, was released in year 1994"
result = re.split(r"\,", text)
print(result)

Выход:

['The film', ' Pulp Fiction', ' was released in year 1994']

Поиск Всех Экземпляров

Функция match проводит сопоставление с первым элементом, в то время как функция search проводит глобальный поиск по строке и возвращает первый сопоставленный экземпляр.

Например, если у нас есть следующая строка:

text = "I want to buy a mobile between 200 and 400 euros"

Мы хотим найти все цифры из этой строки. Если мы используем функцию search , то будет возвращено только первое вхождение цифр, т. е. 200, как показано ниже:

result = re.search(r"\d+", text)
print(result.group(0))

Выход:

200

С другой стороны, функция findall возвращает список, содержащий все совпадающие высказывания, как показано ниже:

text = "I want to buy a mobile between 200 and 400 euros"
result = re.findall(r"\d+", text)
print(result)

Выход:

['200', '400']

Из выходных данных видно, что и “200”, и “400” возвращаются функцией findall .

Вывод

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