Опубликован: 22.12.2005 | Доступ: свободный | Студентов: 16667 / 511 | Оценка: 4.18 / 3.71 | Длительность: 16:16:00
ISBN: 978-5-9556-0109-0
Лекция 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)

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

Андрей Егоров
Андрей Егоров

def bin(n):

"""Цифры двоичного представления натурального числа """

if n == 0:

   return []

n, d = divmod(n, 2)

return bin(n) + [d]

print bin(69)

Что значит здесь return[] ? Возвращает список? Непонятно какой список? Откуда он? 

 

 

Асмик Гаряка
Асмик Гаряка

Почему при вычислении рейтинга не учитывается уровень, как описано? Для всех курсов У=1, хотя для Специалист должно быть 2.

Александр Воронцов
Александр Воронцов
Украина