Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Python: регулярные выражения  (Прочитано 1006 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Jack Sparrow

  • Автор темы
  • Активист
  • *
  • Сообщений: 641
    • Просмотр профиля
Python: регулярные выражения
« : 10 Июня 2013, 21:25:26 »
Имеется текстовый файл, представляющий из себя плоскую базу данных. Записи отделяются пустой строкой. Поля обозначаются так: \xy (бэк-слеш и потом две буквы). После пробела идут данные. Пример:
\xy hello
\zy world

\xy jack sparrow
\ab is
\cd pirate



Здесь две записи. В первой два поля, во второй - три. Примем, что каждая запись начинается с одинакового маркера поля (в данном случае это \xy).
Такой файл нужно распарсить так, чтобы это был список списков. Парсить на отдельные поля не нужно. Т.е. для данных, приведенных выше, должен быть список из двух элементов. Первый элемент:
"""
\xy hello
\zy world
"""
Второй должен быть аналогичным. Т.е. каждый элемент должен быть многострочной строкой. Подумал, что проще всего будет распарсить это с помощью регулярных выражений.
Вот пробный текст и код:
Код: (Python) [Выделить]
#!/usr/bin/env python

import re

text = r"""

\xy hello
\xz world
\zz mother
\ab father
\bc 2013

\xy my
\xy name
\zy is
\bc jack
\de sparrow
\mn he or she
\zz 2010

\xy a34
\yx 3
\zy det
\mn the
\pr rock
\st the
\zy 222

"""
# Составляем регулярное выражение. В нем-то вся и загвоздка
pattern = re.compile(r"""
\\xy[ ]  # ищет \xy и пробел
[\S]+    # ищет 1 и больше любых символов, кроме непечатных
\n\n     # ищет два символа новой строки, идущих подряд
         # по идее, это должно отделять одну запись от другой
""", re.VERBOSE)

res = pattern.findall(text) # это выражение возвращает список

# Выводим результат
for i in res:
    print(i)

print(len(res)) # длина списка
Какая-то загвоздка с регурярным выражением, конкретно - \n\n. По моему мнению, это должно отделять одну запись от другой, т.к. каждая запись заканчивается знаком \n, а потом еще идет еще один символ новой строки. Т.е. всего их два между каждой записью. Но этот код, почему-то, не работает. Если \n\n вообще убрать, то результат будет таким:
\xy hello
\xy my
\xy name
\xy a34
4

Здесь каждая запись состоит только из одного поля \xy, да и то, одно из них лишнее, т.к. во второй записи есть два одинаковых поля. А 4 тут показывает количество элементов в списке (должно быть три).
Что здесь не так?


Пользователь решил продолжить мысль 11 Июня 2013, 12:24:57:
Сегодня утром еще в полудреме в голову пришло гениальное (т.е. простое) решение.
Код: (Python) [Выделить]
res = text.split('\n\n')
Все так просто, однако... тоже не работает  :-[ Вернее, работает, но не так, как нужно, не разбивает по '\n\n'.
Если вывести текст через функцию repr, то видно, что там записи разделяются двумя символами новой строки:
Код: (Python) [Выделить]
'\n\n\\xy hello\n\\xz world\n\\zz mother\n\\ab father\n\\bc 2013\n\n\\xy my\n\\xy name\n\\zy is\n\\bc jack\n\\de sparrow\n\\mn he or she\n\\zz 2010\n\n\\xy a34\n\\yx 3\n\\zy det\n\\mn the\n\\pr rock\n\\st the\n\\zy 222\n\n'
Что-то странное есть в этих новых строках.


Пользователь решил продолжить мысль 11 Июня 2013, 17:47:38:
Внезапно все заработало. Этот код:
Код: (Python) [Выделить]
res = text.split('\n\n')Вроде бы ничего особо не менял. Попробовал создать другой текстовый файл, и заработало. Потом заработало и в других. Даже и не знаю, в чем было дело.
« Последнее редактирование: 11 Июня 2013, 17:47:38 от Jack Sparrow »
Нейросети тебя не заменят. Тебя заменит человек, который умеет ими пользоваться.

 

Страница сгенерирована за 0.54 секунд. Запросов: 26.