Опубликован: 22.12.2005 | Уровень: для всех | Доступ: платный
Лекция 6:

Обработка текстов. Регулярные выражения. Unicode

Примеры применения регулярного выражения

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

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

import re
log_re = re.compile(r"""(?P<date>[A-Za-z]{3}\s+\d+\s+\d\d:\d\d:\d\d) \S+ kernel: 
 PAY: .+ DST=(?P<dst>\S+).* LEN=(?P<len>\d+).* DPT=(?P<dpt>\d+) """)

for line in open("message.log"):
  m = log_re.match(line)
  if m:
     print "%(date)s %(dst)s:%(dpt)s size=%(len)s" % m.groupdict()

В результате получается

Nov 27 15:57:59 192.168.1.115:1039 size=1500
Nov 27 15:57:59 192.168.1.200:8080 size=40
Nov 27 15:57:59 192.168.1.115:1039 size=515
Nov 27 15:57:59 192.168.1.200:8080 size=40
Nov 27 15:57:59 192.168.1.115:1039 size=40
Nov 27 15:57:59 192.168.1.200:8080 size=40
Nov 27 15:57:59 192.168.1.115:1039 size=40

Анализ записи числа

Хороший пример регулярного выражения можно найти в модуле fpformat. Это регулярное выражение позволяет разобрать запись числа (в том виде, в каком числовой литерал принято записывать в Python):

decoder = re.compile(r'^([-+]?)0*(\d*)((?:\.\d*)?)(([eE][-+]?\d+)?)$')
# Следующие части числового литерала выделяются с помощью групп:
# \0 - весь литерал
# \1 - начальный знак или пусто
# \2 - цифры слева от точки
# \3 - дробная часть (пустая или начинается с точки)
# \4 - показатель (пустой или начинается с 'e' или 'E')

Например:

import re
decoder = re.compile(r'^([-+]?)0*(\d*)((?:\.\d*)?)((?:[eE][-+]?\d+)?)$')

print decoder.match("12.234").groups()
print decoder.match("-0.23e-7").groups()
print decoder.match("1e10").groups()

Получим

('', '12', '.234', '')
('-', '', '.23', 'e-7')
('', '1', '', 'e10')

Множественная замена

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

import re

def multisub(subs_dict, text):
    def _multisub(match_obj):
        return str(subs_dict[match_obj.group()])

    multisub_re = re.compile("|".join(subs_dict.keys()))
    return multisub_re.sub(_multisub, text)


repl_dict = {'one': 1, 'two': 2, 'three': 3}

print multisub(repl_dict, "One, two, three")

Будет выведено

One, 2, 3

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

В приведенной программе вспомогательная функция _multisub() по полученному объекту с результатом сравнения возвращает значение из словаря с описаниями замен subs_dict.

Работа с несколькими файлами

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

import fileinput
for line in fileinput.input():
    process(line)

В случае, когда файлов не задано, обрабатывается стандартный ввод.

Сергей Крупко
Сергей Крупко

Добрый день.

Я сейчас прохожу курс  повышения квалификации  - "Профессиональное веб-программирование". Мне нужно получить диплом по этому курсу. Я так полагаю нужно его оплатить чтобы получить диплом о повышении квалификации. Как мне оплатить этот курс?

 

Павел Ялганов
Павел Ялганов

Скажите экзамен тоже будет ввиде теста? или там будет какое то практическое интересное задание?

Максим Чиндясов
Максим Чиндясов
Россия, Нижний Новгород
Ольга Коваль
Ольга Коваль
Беларусь, Минск