Python re sub удалить

Примеры применения регулярных выражений в Python

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

Введение в регулярные выражения

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

Эта статья разделена на 2 части.

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

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

Что такое шаблон регулярного выражения и как его скомпилировать?

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

Читайте также:  Content type text html charset utf 8 content transfer encoding

Основным примером является \s+ .
Здесь \ s соответствует любому символу пробела. Добавив в конце оператор + , шаблон будет иметь не менее 1 или более пробелов. Этот шаблон будет соответствовать даже символам tab \t .

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

>>> import re >>> regex = re.compile('\s+') 

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

Как разбить строку, разделенную регулярным выражением?

Рассмотрим следующий фрагмент текста.

>>> text = """100 ИНФ Информатика 213 МАТ Математика 156 АНГ Английский""" 

У меня есть три курса в формате “[Номер курса] [Код курса] [Название курса]”. Интервал между словами разный.

Передо мной стоит задача разбить эти три предмета курса на отдельные единицы чисел и слов. Как это сделать?
Их можно разбить двумя способами:

# Разделит текст по 1 или более пробелами >>> re.split('\s+', text) # или >>> regex.split(text) ['100', 'ИНФ', 'Информатика', '213', 'МАТ', 'Математика', '156', 'АНГ', 'Английский'] 

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

Поиск совпадений с использованием findall, search и match

Предположим, вы хотите извлечь все номера курсов, то есть 100, 213 и 156 из приведенного выше текста. Как это сделать?

Что делает re.findall()?

#найти все номера в тексте >>> print(text) 100 ИНФ Информатика 213 МАТ Математика 156 АНГ Английский >>> regex_num = re.compile('\d+') >>> regex_num.findall(text) ['100', '213', '156'] 

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

Подобно + , есть символ * , для которого требуется 0 или более чисел. Это делает наличие цифры не обязательным, чтобы получилось совпадение. Подробнее об этом позже.

В итоге, метод findall извлекает все вхождения 1 или более номеров из текста и возвращает их в список.

re.search() против re.match()

Как понятно из названия, regex.search() ищет шаблоны в заданном тексте.
Но, в отличие от findall , который возвращает согласованные части текста в виде списка, regex.search() возвращает конкретный объект соответствия. Он содержит первый и последний индекс первого соответствия шаблону.

Аналогично, regex.match() также возвращает объект соответствия. Но разница в том, что он требует, чтобы шаблон находился в начале самого текста.

>>> # создайте переменную с текстом >>> text2 = """ИНФ Информатика 213 МАТ Математика 156""" >>> # скомпилируйте regex и найдите шаблоны >>> regex_num = re.compile('\d+') >>> s = regex_num.search(text2) >>> print('Первый индекс: ', s.start()) >>> print('Последний индекс: ', s.end()) >>> print(text2[s.start():s.end()]) Первый индекс: 17 Последний индекс: 20 213 

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

>>> print(s.group()) 205 >>> m = regex_num.match(text2) >>> print(m) None 

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

Для изменения текста, используйте regex.sub() .
Рассмотрим следующую измененную версию текста курсов. Здесь добавлена табуляция после каждого кода курса.

# создайте переменную с текстом >>> text = """100 ИНФ \t Информатика 213 МАТ \t Математика 156 АНГ \t Английский""" >>> print(text) 100 ИНФ Информатика 213 МАТ Математика 156 АНГ Английский 

Из вышеприведенного текста я хочу удалить все лишние пробелы и записать все слова в одну строку.

Для этого нужно просто использовать regex.sub для замены шаблона \s+ на один пробел .

# заменить один или больше пробелов на 1 >>> regex = re.compile('\s+') >>> print(regex.sub(' ', text)) 
>>> print(re.sub('\s+', ' ', text)) 101 COM Computers 205 MAT Mathematics 189 ENG English 

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

Это можно сделать, используя отрицательное соответствие (?!\n) . Шаблон проверяет наличие символа новой строки, в python это \n , и пропускает его.

# убрать все пробелы кроме символа новой строки >>> regex = re.compile('((?!\n)\s+)') >>> print(regex.sub(' ', text)) 100 ИНФ Информатика 213 МАТ Математика 156 АНГ Английский 

Группы регулярных выражений

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

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

>>> text = """100 ИНФ Информатика 213 МАТ Математика 156 АНГ Английский""" # извлечь все номера курсов >>> re.findall('5+', text) # извлечь все коды курсов (для латиницы [A-Z]) >>> re.findall('[А-ЯЁ]', text) # извлечь все названия курсов >>> re.findall('[а-яА-ЯёЁ]', text) ['100', '213', '156'] ['ИНФ', 'МАТ', 'АНГ'] ['Информатика', 'Математика', 'Английский'] 

Давайте посмотрим, что получилось.
Я скомпилировал 3 отдельных регулярных выражения по одному для соответствия номерам курса, коду и названию.
Для номера курса, шаблон 8+ указывает на соответствие всем числам от 0 до 9. Добавление символа + в конце заставляет найти по крайней мере 1 соответствие цифрам 0-9. Если вы уверены, что номер курса, будет иметь ровно 3 цифры, шаблон мог бы быть 2 .

Для кода курса, как вы могли догадаться, [А-ЯЁ] будет совпадать с 3 большими буквами алфавита А-Я подряд (буква “ё” не включена в общий диапазон букв).

Для названий курса, [а-яА-ЯёЁ] будем искать а-я верхнего и нижнего регистра, предполагая, что имена всех курсов будут иметь как минимум 4 символа.

Можете ли вы догадаться, каков будет шаблон, если максимальный предел символов в названии курса, скажем, 20?
Теперь мне нужно написать 3 отдельные строки, чтобы разделить предметы. Но есть лучший способ. Группы регулярных выражений.
Поскольку все записи имеют один и тот же шаблон, вы можете создать единый шаблон для всех записей курса и внести данные, которые хотите извлечь из пары скобок ().

# создайте группы шаблонов текста курса и извлеките их >>> course_pattern = '(5+)\s*([А-ЯЁ])\s*([а-яА-ЯёЁ])' >>> re.findall(course_pattern, text) [('100', 'ИНФ', 'Информатика'), ('213', 'МАТ', 'Математика'), ('156', 'АНГ', 'Английский')] 

Обратите внимание на шаблон номера курса: 2+ , код: [А-ЯЁ] и название: [а-яА-ЯёЁ] они все помещены в круглую скобку (), для формирования группы.

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

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

Давайте рассмотрим пример фрагмента HTML, где нам необходимо получить тэг HTML.

>> > text = » Пример жадного соответствия регулярных выражений

Источник

How to delete () using re module in Python

@ThiefMaster: Not everyone has english as his native tongue and is able to correctly and completely express what he wants to say (since english is a second language to me I’ve got a hard time as well quite often).

3 Answers 3

You need to use raw strings, or escape the slashes:

name = re.sub(r'\((.+)\)', r'\1', name) 

@boudou — Actually, You need to escape that backslash as well — the regex engine needs to see \( , so the string should be ‘\\(‘ , or r’\(‘ : ideone.com/X3tEN

You need to escape backslashes in Python strings if followed by a number; the following expressions are all true:

assert '\1' == '\x01' assert len('\\1') == 2 assert '\)' == '\\)' 
name = re.sub('\\((.+)\\)','\\1',name) 

Alternatively, use the regular expression string definition:

name = re.sub(r'\((.+)\)', r'\1',name) 

@boudo ‘\\(‘ is the same as [(] , i.e. match a parenthesis. ‘\(‘ falls back to the default escaping. Your argument applies to regexp strings starting with r’ .

@boudou Yes, that’s precisely what I tried to say by mentioning it falls back to default escaping rules.

name= re.sub('\((.+)\)','\\1',name) 

or if you do not want to have an illisible code with \\ everywhere you are using backslashes, do not escape manually backslashes, but add an r before the string, ex: r»myString\» is the same as «myString\\» .

Linked

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

Site design / logo © 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA . rev 2023.7.27.43548

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Use Regex re.sub to remove everything before and including a specified word

I’ve got a string, which looks like «Blah blah blah, Updated: Aug. 23, 2012», from which I want to use Regex to extract just the date Aug. 23, 2012 . I found an article in the stacks which has something similar: regex to remove all text before a character, but that’s not working either when I tried

date_div = "Blah blah blah, Updated: Aug. 23, 2012" extracted_date = re.sub('^[^Updated]*',"", date_div) 

How can I remove everything up to and including Updated, so that only Aug. 23, 2012 is left over? Thanks!

3 Answers 3

In this case, you can do it withot regex, e.g:

>>> date_div = "Blah blah blah, Updated: Aug. 23, 2012" >>> date_div.split('Updated: ') ['Blah blah blah, ', 'Aug. 23, 2012'] >>> date_div.split('Updated: ')[-1] 'Aug. 23, 2012' 
import re date_div = "Blah blah blah, Updated: Aug. 23, 2012" extracted_date = re.sub('^(.*)(?=Updated)',"", date_div) print extracted_date 

EDIT
If MattDMo’s comment below is correct and you want to remove the «Update: » as well you can do:

extracted_date = re.sub('^(.*Updated: )',"", date_div) 

With a regex, you may use two regexps depending on the occurrence of the word:

# Remove all up to the first occurrence of the word including it (non-greedy): ^.*?word # Remove all up to the last occurrence of the word including it (greedy): ^.*word 

The ^ matches the start of string position, .*? matches any 0+ chars (mind the use of re.DOTALL flag so that . could match newlines) as few as possible ( .* matches as many as possible) and then word matches and consumes (i.e. adds to the match and advances the regex index) the word.

Note the use of re.escape(up_to_word) : if your up_to_word does not consist of sole alphanumeric and underscore chars, it is safer to use re.escape so that special chars like ( , [ , ? , etc. could not prevent the regex from finding a valid match.

import re date_div = "Blah blah\nblah, Updated: Aug. 23, 2012 Blah blah Updated: Feb. 13, 2019" up_to_word = "Updated:" rx_to_first = r'^.*?<>'.format(re.escape(up_to_word)) rx_to_last = r'^.*<>'.format(re.escape(up_to_word)) print("Remove all up to the first occurrence of the word including it:") print(re.sub(rx_to_first, '', date_div, flags=re.DOTALL).strip()) print("Remove all up to the last occurrence of the word including it:") print(re.sub(rx_to_last, '', date_div, flags=re.DOTALL).strip()) 
Remove all up to the first occurrence of the word including it: Aug. 23, 2012 Blah blah Updated: Feb. 13, 2019 Remove all up to the last occurrence of the word including it: Feb. 13, 2019 

Источник

Оцените статью