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

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

В чем преимущества регулярных выражений?

Рассмотрим примеры поиска email и телефонного номера в большом текстовом файле.

  1. Первый пример ищет email с использованием строгого регулярного выражения, проверяющего формат адреса.
  2. Второй пример ищет email без использования регулярных выражений, что делает код менее читаемым и гибким.
  3. Третий пример находит номер телефона с использованием регулярных выражений и затем удаляет все символы, кроме цифр.
  4. Четвертый пример ищет номер телефона без использования регулярных выражений, что также делает код менее компактным и подверженным ошибкам.

Пример 1: Поиск email с использованием регулярных выражений:

import re

def find_emails_with_regex(text):
    pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
    result = re.findall(pattern, text)
    return result

Пример 2: Поиск email без использования регулярных выражений:

def find_emails_in_array(text_array):
    result = []

    for text in text_array:
        words = text.split()
        for word in words:
            if '@' in word and '.' in word:
                # Дополнительная проверка на недопустимые символы
                if all(char.isalpha() or char.isdigit() or char in ['.', '_', '-', '%', '+'] for char in word):
                    result.append(word)

    return result

Пример 3: Поиск номеров телефонов с использованием регулярных выражений:

import re

def find_phone_numbers_with_regex(text):
    pattern = r'[\d()+\- ]+'
    # Находим номер телефона с использованием регулярного выражения
    matched_text = re.search(pattern, text).group()
    # Очищаем номер телефона от лишних символов
    result = re.sub(r'\D', '', matched_text)
    return result

Пример 4: Поиск номеров телефонов в массиве текста с очисткой от лишних символов:

def find_phone_numbers_in_array(text_array):
    result = []

    for text in text_array:
        chars_to_remove = '()-+ '
        current_phone = ''

        for char in text:
            if char.isdigit() or char in chars_to_remove:
                current_phone += char

        # Добавляем только непустые номера телефонов
        if current_phone:
            result.append(current_phone)

    return result

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

  1. Ограниченная точность: Простые методы, такие как разделение строки на слова и поиск определенных символов, не гарантируют точное соответствие формату, и могут ошибочно находить или пропускать нужные элементы. Например, при поиске email адресов, подход с простым поиском символа «@» и «.» может привести к неверным результатам.
  2. Низкая гибкость: Методы без использования регулярных выражений могут быть менее гибкими в адаптации к различным форматам данных. Если формат данных изменится, код также потребует изменений.
  3. Больше кода: Для решения сложных задач без регулярных выражений может потребоваться написание большего объема кода, что сделает его менее читаемым и увеличит вероятность ошибок.
  4. Неудобство в обслуживании: Обслуживание и расширение кода может стать сложнее без использования регулярных выражений, особенно при необходимости внесения изменений в условия поиска.
  5. Отсутствие поддержки специфичных форматов: Некоторые задачи, такие как поиск email адресов или номеров телефонов, имеют четкие форматы, которые легко описываются регулярными выражениями, но которые сложно обработать с использованием простых методов.

Преимущества регулярных выражений:

  1. Гибкость и мощь: Регулярные выражения позволяют создавать сложные шаблоны, охватывающие различные случаи и форматы текста. Это делает их эффективным средством для поиска и извлечения информации из текстовых данных.
  2. Универсальность: Регулярные выражения поддерживаются во многих языках программирования и текстовых редакторах, что делает их универсальным инструментом для обработки текста в различных сценариях.
  3. Эффективность: При правильном использовании регулярные выражения могут быть очень эффективными, особенно при работе с большими объемами текстовых данных.
  4. Компактность: С помощью регулярных выражений можно описать сложные условия поиска и замены с использованием относительно короткого шаблона, что делает код более читаемым и компактным.
  5. Автоматизация: Регулярные выражения позволяют автоматизировать процессы обработки текста, что особенно важно при анализе и преобразовании больших объемов данных.

Синтаксис регулярных выражений.

Основные символы, используемые в регулярных выражениях.

  1. . (точка)
    • Назначение: Соответствует любому символу, кроме символа новой строки (\n).
    • Пример: a.c соответствует строкам «abc», «adc», «a1c», и т. д.
  2. * (звездочка)
    • Назначение: Соответствует нулю или более повторениям предыдущего символа или группы символов.
    • Пример: ab*c соответствует «ac», «abc», «abbc», «abbbc», и так далее.
  3. + (плюс)
    • Назначение: Соответствует одному или более повторениям предыдущего символа или группы символов.
    • Пример: ab+c соответствует «abc», «abbc», «abbbc», и так далее.
  4. ? (вопросительный знак)
    • Назначение: Соответствует нулю или одному повторению предыдущего символа или группы символов.
    • Пример: ab?c соответствует «ac» и «abc».
  5. ^ (caret)
    • Назначение: Соответствует началу строки.
    • Пример: ^abc соответствует строкам, начинающимся с «abc».
  6. $ (доллар)
    • Назначение: Соответствует концу строки.
    • Пример: abc$ соответствует строкам, заканчивающимся на «abc».
  7. [ ] (квадратные скобки)
    • Назначение: Соответствует одному из символов, перечисленных в скобках.
    • Пример: [aeiou] соответствует любой гласной букве.
  8. [^ ] (квадратные скобки с отрицанием)
    • Назначение: Соответствует любому символу, не входящему в список в скобках.
    • Пример: [^0-9] соответствует любому символу, не являющемуся цифрой.
  9. | (вертикальная черта)
    • Назначение: Или (или «или это, или то»).
    • Пример: cat|dog соответствует «cat» или «dog».
  10. ( ) (круглые скобки)
    • Назначение: Группировка выражения.
    • Пример: (ab)+ соответствует «ab», «abab», «ababab», и так далее.
  11. \ (обратная косая черта)
    • Назначение: Экранирование специальных символов. Например, \., \\ и так далее.
  12. \d, \D, \w, \W, \s, \S
    • Назначение: Специальные последовательности для соответствия цифрам (\d), не цифрам (\D), буквам и цифрам (\w), не буквам и не цифрам (\W), пробелам (\s), и не пробелам (\S).
  1. { } (фигурные скобки)
  • Назначение: Указание конкретного количества повторений предыдущего символа или группы символов.
  • Примеры:
    • \d{2,4} — соответствует двум, трём или четырём цифрам.
    • [a-zA-Z]{3} — соответствует трем буквам (регистр не имеет значения).
  1. \b, \B
  • Назначение: Границы слова (\b) и отсутствие границы слова (\B).
  • Пример:
    • \bword\b — соответствует слову «word» как отдельному слову, но не включает «words» или «password».
    • \Bword\B — соответствует «word» только если оно является частью другого слова.
  1. (?i), (?s)
  • Назначение: Установка флагов для регистронезависимого поиска ((?i)) и режима «точка также совпадает с символом новой строки» ((?s)).
  • Пример:
    • (?i)case-insensitive — соответствует «case-insensitive», «CASE-INSENSITIVE», и так далее.
  1. (?= ), (?! )
  • Назначение: Позитивное впереди смотрящее утверждение ((?= )) и негативное впереди смотрящее утверждение ((?! )).
  • Примеры:
    • \d(?=px) — соответствует цифре, если за ней следует «px».
    • \d(?!px) — соответствует цифре, только если за ней НЕ следует «px».
  1. (?: )
  • Назначение: Негруппирующие скобки, которые позволяют группировать выражение без сохранения результатов.
  • Пример:
    • (?:ab)+ — соответствует «ab», «abab», «ababab», и так далее, но не создает захватывающих групп.
  1. \1, \2, ...
  • Назначение: Обратные ссылки на захватывающие группы. \1 ссылается на первую группу, \2 — на вторую, и так далее.
  • Пример:
    • (\d{2})-\1 — соответствует парам чисел, разделенных дефисом, где обе части одинаковы (например, «12-12», «34-34»).
  1. *?, +?, ??
  • Назначение: Ленивые (нежадные) версии квантификаторов *, +, и ?, которые соответствуют как можно меньшему количеству символов.
  • Пример:
    • a+?b — соответствует самому короткому возможному сочетанию символов «a» и «b» в строке.
  1. \A, \Z
  • Назначение: Соответствует началу строки (\A) и концу строки (\Z), игнорируя символ новой строки.
  • Пример:
    • \Astart — соответствует строкам, начинающимся с «start».
    • end\Z — соответствует строкам, заканчивающимся на «end».

Основные понятия, используемые в регулярных выражениях

  1. Метакаретка (^, $):
    • Метакаретка — это специальный символ, который помогает нам указать, где должно начинаться (^) или заканчиваться ($) соответствие в строке.
    • Пример: ^Hello соответствует строкам, начинающимся с «Hello».
  2. Набор символов ([ ]):
    • Набор символов — это группа символов, из которых должен быть выбран один.
    • Пример: [aeiou] соответствует любой гласной букве.
  3. Квантификация (*, +, ?):
    • Эти символы позволяют нам указать, сколько раз предыдущий символ или группа символов могут повторяться.
    • * — 0 или более раз.
    • + — 1 или более раз.
    • ? — 0 или 1 раз.
    • Пример: ab*c соответствует «ac», «abc», «abbc», «abbbc», и так далее.

Пример квантификации с использованием фигурных скобок:

  • Регулярное выражение ^[\d]{2,4}$ говорит: «Начни со строки, затем должны быть от 2 до 4 цифр, и закончи строку». Это соответствует строкам вроде «123», «4567», «8901», но не соответствует строкам «12a» или «12345».

Группировка в RegExp

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

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

  1. Группировка выражений:
    • Цель: Объединение частей регулярного выражения для обработки как единого блока.
    • Пример: (ab)+ — создает группу для подвыражения «ab», а затем + указывает, что это подвыражение может повторяться один или более раз.
  2. Захват результатов:
    • Цель: Захват значений, соответствующих определенным частям регулярного выражения.
    • Пример: (\d{2})-(\d{2})-(\d{4}) — создает три группы для захвата дня, месяца и года в дате в формате «DD-MM-YYYY».
  3. Обратные ссылки:
    • Цель: Использование значений, захваченных в группе, внутри того же регулярного выражения.
    • Пример: (\w+) \1 — соответствует строкам, где одно и то же слово повторяется дважды, например, «apple apple» или «cat cat».
  4. Логические операции:
    • Цель: Группы позволяют создавать сложные логические выражения.
    • Пример: (cat|dog) — создает группу, в которой указано «или» между «cat» и «dog», что соответствует строкам содержащим «cat» или «dog».
  5. Негруппирующие скобки (?: ):
    • Цель: Создание группы без захвата результатов.
    • Пример: (?:ab)+ — группирует «ab», но не сохраняет результат в захватываемой группе.

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

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

Обратные ссылки обычно выражаются с использованием символов \ и номера группы. Как они работают:

  • \1: Ссылка на текст, совпадающий с первой захваченной группой.
  • \2: Ссылка на текст, совпадающий со второй захваченной группой.
  • И так далее…

Примеры использования обратных ссылок.

Пример 1: Поиск повторяющихся слов:

import re

pattern = r'\b(\w+)\b\s+\1\b'
text = 'This is a test test.'

match = re.search(pattern, text)

if match:
    print(f'Found repeated word: {match.group()}')
else:
    print('No repeated word found')


#Found repeated word: test test

В этом примере шаблон \b(\w+)\b\s+\1\b ищет повторяющиеся слова. Обратная ссылка \1 ссылается на текст, совпадающий с первой захваченной группой, в данном случае, это слово «test».

Пример 2: Замена повторяющихся слов:

import re

pattern = r'\b(\w+)\b\s+\1\b'
text = 'This is a test test.'

new_text = re.sub(pattern, r'\1', text)

print(f'Original: {text}')
print(f'Replaced: {new_text}')

#Original: This is a test test.
#Replaced: This is a test.

В этом примере с использованием re.sub повторяющиеся слова удаляются из текста.

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

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

  1. Regex101 (https://regex101.com/):
    • Особенности:
      • Интерактивная песочница для тестирования регулярных выражений.
      • Объяснения шагов и сопоставлений.
      • Возможность выбора разных флагов (например, регистронезависимость).
  2. Regexr (https://regexr.com/):
    • Особенности:
      • Интерактивный редактор с примерами и объяснениями.
      • Возможность сохранения и загрузки регулярных выражений.
      • Поддержка разных флагов.
  3. RegExPal (https://www.regexpal.com/):
    • Особенности:
      • Простой и понятный интерфейс для тестирования регулярных выражений.
      • Встроенные примеры и шаблоны.
  4. RegexOne (https://regexone.com/):
    • Особенности:
      • Интерактивные уроки по изучению регулярных выражений.
      • Постепенно увеличивающаяся сложность задач.
  5. Exercism.io (https://exercism.io/):
    • Особенности:
      • Платформа для онлайн-обучения программированию.
      • Включает задачи, связанные с регулярными выражениями.
  6. HackerRank (https://www.hackerrank.com/domains/tutorials/10-days-of-javascript):
    • Особенности:
      • Сайт с задачами и учебными материалами.
      • Раздел «10 Days of JavaScript» включает в себя уроки по регулярным выражениям на JavaScript.
  7. LeetCode (https://leetcode.com/):
    • Особенности:
      • Платформа для подготовки к собеседованиям в IT.
      • Задачи по регулярным выражениям в различных языках программирования.

Модуль re в Python

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

  1. re.search(pattern, string, flags=0):
    • Поиск первого совпадения с шаблоном в строке.
    • Возвращает объект с информацией о совпадении или None, если совпадений нет.
      import re
      
      pattern = r'\d+'
      text = 'The price is $42.50'
      match = re.search(pattern, text)
      
      if match:
          print(f'Found: {match.group()}')
      else:
          print('No match')
      
  2. re.match(pattern, string, flags=0):
    • Проверка совпадения шаблона только в начале строки.
    • Возвращает объект с информацией о совпадении или None, если совпадений в начале строки нет.
      import re
      
      pattern = r'\d+'
      text = '42 is the answer.'
      match = re.match(pattern, text)
      
      if match:
          print(f'Found at the beginning: {match.group()}')
      else:
          print('No match at the beginning')
      
  3. re.findall(pattern, string, flags=0):
    • Поиск всех совпадений шаблона в строке.
    • Возвращает список всех найденных совпадений.
      import re
      
      pattern = r'\d+'
      text = 'There are 42 apples and 30 oranges.'
      matches = re.findall(pattern, text)
      
      print(f'Found: {matches}')
      
  4. re.finditer(pattern, string, flags=0):
    • Поиск всех совпадений шаблона в строке.
    • Возвращает итератор, который возвращает объекты с информацией о каждом совпадении.
      import re
      
      pattern = r'\d+'
      text = 'There are 42 apples and 30 oranges.'
      matches_iter = re.finditer(pattern, text)
      
      for match in matches_iter:
          print(f'Found: {match.group()} at position {match.start()}')
      
  5. re.sub(pattern, replacement, string, count=0, flags=0):
    • Замена совпадений шаблона в строке на указанную подстановку.
    • Возвращает новую строку.
      import re
      
      pattern = r'\d+'
      text = 'There are 42 apples and 30 oranges.'
      new_text = re.sub(pattern, 'X', text)
      
      print(f'Original: {text}')
      print(f'Replaced: {new_text}')
      
  6. Флаги:
    • Флаги добавляют дополнительные опции к работе с регулярными выражениями. Например, re.IGNORECASE делает поиск нечувствительным к регистру.
      import re
      
      pattern = r'apple'
      text = 'I like Apple and banana.'
      match = re.search(pattern, text, flags=re.IGNORECASE)
      
      if match:
          print(f'Found: {match.group()}')
      else:
          print('No match')
      

Флаги в регулярках

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

  1. re.IGNORECASE (re.I):
    • Делает регулярное выражение нечувствительным к регистру.
      re.search('apple', 'Apple', re.IGNORECASE)
      
  2. re.MULTILINE (re.M):
    • Позволяет ^ и $ соответствовать началу и концу каждой строки, а не всей строке целиком.
      re.search('^start', 'start\nend', re.MULTILINE)
      
  3. re.DOTALL (re.S):
    • Позволяет . соответствовать любому символу, включая символ новой строки \n.
      re.search('a.b', 'a\nb', re.DOTALL)
      
  4. re.VERBOSE (re.X):
    • Разрешает использование пробелов и комментариев внутри регулярного выражения для улучшения читаемости.
      re.search(r'''
          \d+   # Цифры
          [a-z]+  # Слова
      ''', '42 apples', re.VERBOSE)
      
  5. re.ASCII (re.A):
    • Делает регулярное выражение чувствительным к ASCII. Влияет на интерпретацию \w, \b, \d и т. д.
      re.search(r'\w+', 'résumé', re.ASCII)
      
  6. re.UNICODE (re.U):
    • Делает регулярное выражение чувствительным к Unicode. Влияет на интерпретацию \w, \b, \d и т. д.
      re.search(r'\w+', 'résumé', re.UNICODE)
      
  7. re.LOCALE (re.L):
    • Делает регулярное выражение зависимым от текущей локали. Влияет на интерпретацию \w, \b, \d и т. д.
      re.search(r'\w+', 'résumé', re.LOCALE)
      

Эти флаги могут быть использованы в комбинациях, добавляя их вторым аргументом к функциям модуля re, таким как re.search(), re.match(), re.findall(), re.sub(), и так далее. Например, re.IGNORECASE | re.MULTILINE указывает одновременное использование флагов IGNORECASE и MULTILINE.

Примеры поиска с помощью re

Пример 1: Простой поиск:

import re

pattern = r'\d+'  # Шаблон для поиска одной или более цифр
text = 'There are 42 apples and 30 oranges.'

match = re.search(pattern, text)

if match:
    print(f'Found: {match.group()}')
else:
    print('No match')

#Found: 42

Пример 2: Поиск нескольких совпадений и их перебор:

import re

pattern = r'\d+'  # Шаблон для поиска одной или более цифр
text = 'There are 42 apples and 30 oranges.'

matches = re.findall(pattern, text)

print(f'Found: {matches}')

#Found: ['42', '30']

Пример 3: Работа с группами в найденных выражениях:

import re

pattern = r'(\d+) (\w+)'  # Шаблон для поиска цифр, за которыми следует слово
text = 'There are 42 apples and 30 oranges.'

matches = re.finditer(pattern, text)

for match in matches:
    print(f'Number: {match.group(1)}, Fruit: {match.group(2)}')

#Number: 42, Fruit: apples
#Number: 30, Fruit: oranges

Замена с помощью регулярных выражений

Пример 1: Полная замена

import re

pattern = r'\d+'  # Шаблон для поиска одной или более цифр
text = 'There are 42 apples and 30 oranges.'

new_text = re.sub(pattern, 'X', text)

print(f'Original: {text}')
print(f'Replaced: {new_text}')

#Original: There are 42 apples and 30 oranges.
#Replaced: There are X apples and X oranges.

Пример 2: Замена нескольких совпадений

import re

pattern = r'\d+'  # Шаблон для поиска одной или более цифр
text = 'There are 42 apples and 30 oranges.'

new_text = re.sub(pattern, 'X', text, count=2)

print(f'Original: {text}')
print(f'Replaced: {new_text}')

#Original: There are 42 apples and 30 oranges.
#Replaced: There are X apples and X oranges.

Пример 3: Замена с использованием групп

import re

pattern = r'(\d+) (\w+)'  # Шаблон для поиска цифр, за которыми следует слово
text = 'There are 42 apples and 30 oranges.'

new_text = re.sub(pattern, r'\2-\1', text)

print(f'Original: {text}')
print(f'Replaced: {new_text}')

#Original: There are 42 apples and 30 oranges.
#Replaced: There are apples-42 and oranges-30.

Пример 4: Замена с использованием паттерна в тексте на который заменяется исходный текст

import re

pattern = r'\d+'  # Шаблон для поиска одной или более цифр
text = 'There are 42 apples and 30 oranges.'
replacement_pattern = r'Number: \g<0>'

new_text = re.sub(pattern, replacement_pattern, text)

print(f'Original: {text}')
print(f'Replaced: {new_text}')

#Original: There are 42 apples and 30 oranges.
#Replaced: There are Number: 42 apples and Number: 30 oranges.

Используемые конструкции в паттернах замены

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

Обратные ссылки на группы:

  • \1, \2, \3, ...: Обратные ссылки на захватывающие группы. Эти символы вставляют текст, найденный в соответствующей группе.
    import re
    
    pattern = r'(\d+) (\w+)'
    text = 'There are 42 apples.'
    
    # Замена на "Number: <цифры>"
    new_text = re.sub(pattern, r'Number: \1', text)
    print(new_text)
    
    #There are Number: 42 apples.
    

Группы по именам:

  • \g<name>: Обратная ссылка на захватывающую группу по имени.
    import re
    
    pattern = r'(?P<digits>\d+) (?P<fruit>\w+)'
    text = 'There are 42 apples.'
    
    # Замена на "Number: <цифры>"
    new_text = re.sub(pattern, r'Number: \g<digits>', text)
    print(new_text)
    
    #There are Number: 42 apples.
    

Литералы и текст:

  • Любой текст, не являющийся спецсимволом или обратной ссылкой, вставляется в результирующий текст как есть.
    import re
    
    pattern = r'(\d+) (\w+)'
    text = 'There are 42 apples.'
    
    # Замена на "Count: 1, Type: apples"
    new_text = re.sub(pattern, r'Count: 1, Type: apples', text)
    print(new_text)
    
    #There are Count: 1, Type: apples.
    

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

Обработка логов

Дан файл access.log веб сервера nginx. Необходимо получить информацию о времени, ip адресе и запрашиваемом url при доступе к сайту.

Допустим, у вас есть файл access.log nginx с записями в формате:

127.0.0.1 - - [10/Jan/2024:12:30:45 +0000] "GET /page1 HTTP/1.1" 200 1234
192.168.1.1 - - [10/Jan/2024:12:31:15 +0000] "GET /page2 HTTP/1.1" 404 5678

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

import re

# Определение шаблона для извлечения информации из записей access.log
log_pattern = re.compile(r'(?P<ip>\d+\.\d+\.\d+\.\d+) - - \[(?P<timestamp>[^\]]+)\] "(?P<method>[A-Z]+) (?P<url>[^"]+)" \d+ \d+')

# Открытие файла и чтение строк
with open('access.log', 'r') as file:
    for line in file:
        # Поиск совпадения в каждой строке
        match = log_pattern.search(line)
        
        if match:
            # Извлечение информации из совпадения
            ip_address = match.group('ip')
            timestamp = match.group('timestamp')
            method = match.group('method')
            url = match.group('url')

            # Вывод извлеченной информации
            print(f'IP: {ip_address}, Time: {timestamp}, Method: {method}, URL: {url}')

В данном коде:

  • log_pattern представляет собой регулярное выражение, составленное для извлечения информации из записей access.log.
  • Затем файл access.log открывается, и каждая строка обрабатывается с использованием регулярного выражения.
  • Если совпадение найдено, информация извлекается и выводится на экран.

Метод re.compile() в модуле re в Python используется для компиляции регулярного выражения в объект регулярного выражения. Это может повысить производительность, если вы собираетесь использовать одно и то же регулярное выражение во многих местах кода, так как объект регулярного выражения может быть повторно использован.

Разбор html файла с помощью регулярных выражений

Обработка HTML с использованием регулярных выражений может быть не самым рекомендуемым способом, потому что HTML — это структурированный язык, и лучше всего использовать парсеры HTML для более надежной и безопасной обработки. Например, в Python часто используются библиотеки, такие как BeautifulSoup или lxml.

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

import re

def process_html(html):
    # Поиск тега <div> с классом class1
    pattern = r'<div\s+class="class1"\s*>(.*?)</div>'
    match = re.search(pattern, html, flags=re.DOTALL)

    if match:
        # Извлечение содержимого и атрибутов тега
        div_content = match.group(1)

        # Замена класса class1 на class2
        modified_div = re.sub(r'class="class1"', 'class="class2"', match.group(0))

        # Заменить весь блок <div> на модифицированный
        modified_html = html.replace(match.group(0), modified_div)

        return modified_html, div_content
    else:
        return html, None

# Пример HTML кода
html_code = '''
<html>
  <body>
    <div class="class1">
      <p>This is some content inside the div.</p>
    </div>
    <div class="other-class">
      <p>This is another div.</p>
    </div>
  </body>
</html>
'''

# Обработка HTML и получение результата
modified_html, div_content = process_html(html_code)

# Вывод результата
print("Modified HTML:")
print(modified_html)

print("\nExtracted Content from class1 div:")
print(div_content)

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

Задания на тренировку регулярных выражений в Python

Задания 1-5: Простые задачи

Задание 1. Поиск цифры в строке: Напишите регулярное выражение, которое находит первую цифру в строке.

Задание 2. Извлечение слова из кавычек: Напишите регулярное выражение, которое извлекает слово, заключенное в кавычки (например, «word»).

Задание 3. Проверка корректности email: Напишите регулярное выражение для проверки, является ли строка корректным email-адресом.

Задание 4. Поиск повторяющихся слов: Напишите регулярное выражение для поиска повторяющихся слов в строке.

Задание 5. Извлечение номера телефона: Напишите регулярное выражение, которое извлекает номер телефона из строки. Учтите различные форматы записи (например, (123) 456-7890 или 123-456-7890).

Решение
import re

# 1. Поиск цифры в строке
pattern_1 = r'\d'
result_1 = re.search(pattern_1, 'Hello123')
print(result_1.group())

# 2. Извлечение слова из кавычек
pattern_2 = r'"(\w+)"'
result_2 = re.search(pattern_2, 'This is a "word" in quotes.')
print(result_2.group(1))

# 3. Проверка корректности email
pattern_3 = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
email = 'user@example.com'
is_valid_email = re.match(pattern_3, email)
print(is_valid_email)

# 4. Поиск повторяющихся слов
pattern_4 = r'\b(\w+)\b\s+\1\b'
result_4 = re.search(pattern_4, 'This is a test test.')
print(result_4.group())

# 5. Извлечение номера телефона
pattern_5 = r'\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}'
phone_number = '123-456-7890'
result_5 = re.search(pattern_5, phone_number)
print(result_5.group())

Задания 6-10: Задачи средней сложности

Задание 6. Поиск HTML-тегов: Напишите регулярное выражение для поиска и извлечения всех HTML-тегов из строки.

Задание 7. Извлечение даты: Напишите регулярное выражение, которое извлекает дату в формате «DD/MM/YYYY» из строки.

Задание 8. Поиск слова с определенным количеством символов: Напишите регулярное выражение, которое находит все слова в строке, состоящие из 5 букв.

Задание 9. Разбор URL: Напишите регулярное выражение, которое разбирает URL и извлекает протокол, домен и путь.

Задание 10. Поиск IPv6-адреса: Напишите регулярное выражение для поиска IPv6-адреса в строке.

Решение
# Примеры для заданий 6-10

# 6. Поиск HTML-тегов
pattern_6 = r'<[^>]+>'
html_text = '<p>This is <b>bold</b> text.</p>'
result_6 = re.findall(pattern_6, html_text)
print(result_6)

# 7. Извлечение даты
pattern_7 = r'\b\d{2}/\d{2}/\d{4}\b'
text_with_dates = 'Date: 01/15/2022, Meeting on 03/20/2022'
result_7 = re.findall(pattern_7, text_with_dates)
print(result_7)

# 8. Поиск слова с определенным количеством символов
pattern_8 = r'\b\w{5}\b'
text_with_words = 'Hello world, Python is amazing!'
result_8 = re.findall(pattern_8, text_with_words)
print(result_8)

# 9. Разбор URL
pattern_9 = r'(?P<protocol>https?)://(?P<domain>[\w.-]+)/(?P<path>[\w/]*)'
url = 'https://www.example.com/path/to/page'
result_9 = re.match(pattern_9, url)
print(result_9.groupdict())

# 10. Поиск IPv6-адреса
pattern_10 = r'[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}'
ipv6_address = '2001:0db8:85a3:0000:0000:8a2e:0370:7334'
result_10 = re.search(pattern_10, ipv6_address)
print(result_10.group())
Понравилась статья? Поделиться с друзьями:
Школа Виктора Комлева
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!:

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.