Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 5, 2014 19:07:15

zahar
Зарегистрирован: 2013-07-15
Сообщения: 39
Репутация: +  3  -
Профиль   Отправить e-mail  

Парсиинг. Регулярка. datetime

Всем привет. Друзья помогите с такой проблемой.
Например на входе имеется строка вида:
'куча разных букв и цифр': ‘userID’, ‘created’: (2014, 1, 24, 8, 10, 21.0), ‘куча разных букв и цифр’ ‘userID’, ‘created’: (2014, 1, 26, 13, 15, 21.0) и тд

Задача: Нужна выцепить цифры после userID', ‘created’, userID уникален, а эти цифры преобразовать в дату и время (первые четыре -год, вторая -месяц, третья -день, далее четвертая час и пятая минуты, последняя не нужна, 2014.01.24 08:10).
Регуляркой эти данные получил в виде списка:

['2014', '1', '22', '3', '13', '2014', '1', '26', '6', '33', '2014', '1', '27', '6', '12', '2014', '1', '29', '6', '25']

но вижу что как то кривовато все, думаю можно иначе и проще, вот код
list = 'куча разных букв и цифр': 'userID', 'created': (2014, 1, 24, 8, 10, 21.0), 'куча разных букв и цифр' 'userID', 'created': (2014, 1, 26, 13, 15, 21.0) и тд'
t = re.findall('[0-9]+', str(re.findall('\'userID\', \'created\': \([\d]+, [\d]+, [\d]+, [\d]+, [\d]+', str(list))))
print  t
сначала регуляркой ищем уникальное значение userID\', \'created\ и последующие цифры, а затем уже отбираем только цифры. Получаем на выходе значения вида
['2014', '1', '29', '6', '36', '2014', '2', '5', '5', '38']
['2014', '1', '26', '4', '50']
['2014', '1', '26', '4', '53', '2014', '1', '27', '3', '51', '2014', '1', '27', '4', '26', '2014', '1', '27', '5', '5']
['2014', '1', '24', '9', '57']
вот как теперь все это дело преобразовать в datetime , причем на выходе значения могут быть либо один раз (
['2014', '1', '26', '4', '50']
), либо более
['2014', '1', '26', '4', '53', '2014', '1', '27', '3', '51', '2014', '1', '27', '4', '26', '2014', '1', '27', '5', '5']

Надеюсь понятно объяснил… если что дополню.
Заранее благодарен

ЗЫЖ Текст в квадратных скобках не отображается пришлось его заключить в теги хтмл

Отредактировано zahar (Фев. 5, 2014 19:11:18)

Офлайн

#2 Фев. 5, 2014 19:26:27

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

Парсиинг. Регулярка. datetime

регуляркой дергайте всю строку целиком (2014, 1, 24, 8, 10, 21.0)

s = "(2014, 1, 24, 8, 10, 21.0)"
>>> eval(s)
(2014, 1, 24, 8, 10, 21.0)
>>> datetime.datetime(*eval(s)[:-1])
datetime.datetime(2014, 1, 24, 8, 10)
Как то так Думаю строчку вы уже на компоненты разобрали. Только проверьте что для все вариантов данных работает.

Отредактировано PanovSergey (Фев. 5, 2014 19:32:23)

Офлайн

#3 Фев. 5, 2014 19:43:55

zahar
Зарегистрирован: 2013-07-15
Сообщения: 39
Репутация: +  3  -
Профиль   Отправить e-mail  

Парсиинг. Регулярка. datetime

PanovSergey
регуляркой дергайте всю строку целиком (2014, 1, 24, 8, 10, 21.0)
не совсем верное значение s
s = ['2014', '1', '26', '4', '50']
print type(s)
print eval(s)
<type 'list'>
Traceback (most recent call last):
  File "/home/user/test.py", line 52, in <module>
    print eval(s)
TypeError: eval() arg 1 must be a string or code object

Отредактировано zahar (Фев. 5, 2014 19:46:08)

Офлайн

#4 Фев. 5, 2014 19:53:41

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

Парсиинг. Регулярка. datetime

'created': (2014, 1, 24, 8, 10, 21.0)
В ваших исходных данных вы указали именно так Значит регулярка не правильная, грю же дергайте целиком значение не надо его разбивать на компоненты для этого и нужен eval отдаем строку получаем объект tuple

Если у вас получается значение так как вы написали то еще проще
>>> s = ['2014', '1', '26', '4', '50']
>>> datetime.datetime(*[int(x) for x in s])
datetime.datetime(2014, 1, 26, 4, 50)

Отредактировано PanovSergey (Фев. 5, 2014 19:56:04)

Офлайн

#5 Фев. 5, 2014 19:56:30

zahar
Зарегистрирован: 2013-07-15
Сообщения: 39
Репутация: +  3  -
Профиль   Отправить e-mail  

Парсиинг. Регулярка. datetime

PanovSergey
s =
>>> datetime.datetime(*)
Ну ё-маё конечно. спс огромное

Офлайн

#6 Фев. 5, 2014 20:07:27

zahar
Зарегистрирован: 2013-07-15
Сообщения: 39
Репутация: +  3  -
Профиль   Отправить e-mail  

Парсиинг. Регулярка. datetime

PanovSergey
21.
Давайте добьем до конца, один момент, а если значение s будет:
s = ['2014', '1', '24', '3', '27', '2014', '1', '24', '3', '34', '2014', '1', '24', '6', '37']
те надо получить три даты и времени.

Замечу, что значение s варьируется от пустого (это проще) до неизвестного

Отредактировано zahar (Фев. 5, 2014 20:08:24)

Офлайн

#7 Фев. 5, 2014 20:11:01

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

Парсиинг. Регулярка. datetime

Не надо этого делать, у вас исходные данные однозначно представлены датами. Сразу получайте список по 1 дате за раз.

Если не хотите то то что вы сейчас уже получили можно его побить на списки по 5 элементов. Но проще по моему поправить регулярку. А то костыль получается.

И вообще я не понимаю зачем здесь вообще регулярка? У вас ‘created’: однозначно определяет где в строке искомая дата. Я бы тупо по ней строку засплитил и дело с концом

Отредактировано PanovSergey (Фев. 5, 2014 20:14:03)

Офлайн

#8 Фев. 5, 2014 20:24:04

zahar
Зарегистрирован: 2013-07-15
Сообщения: 39
Репутация: +  3  -
Профиль   Отправить e-mail  

Парсиинг. Регулярка. datetime

Дата одна, но время разное. Да и дата может меняться
Ну да ладно, информацию для размышления получил, буду пробовать. Еще раз спасибо за помощь

Отредактировано zahar (Фев. 5, 2014 20:25:51)

Офлайн

#9 Фев. 5, 2014 20:29:49

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

Парсиинг. Регулярка. datetime

Дата одна, но время разное.
Конечно имеется виду по одному набору типа (2014, 1, 24, 8, 10, 21.0), простите некорректно выразился

Офлайн

#10 Фев. 6, 2014 20:12:32

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Парсиинг. Регулярка. datetime

zahar
'куча разных букв и цифр'
например ?

>>> import re
>>> 
>>> def maketime(t):
...     return '{:04}.{:02}.{:02} {:02}:{:02}'.format(*t)
... 
>>> s = """'куча разных букв и цифр': ‘userID’, ‘created’: (2014, 1, 24, 8, 10, 21.0), ‘куча разных букв и цифр’ ‘userID’, ‘created’: (2014, 1, 26, 13, 15, 21.0)"""
>>> 
>>> pat = r'‘created’: \((\d+), (\d+), (\d+), (\d+), (\d+), [\d.]+\)'
>>> 
>>> lst = [tuple(map(int, i)) for i in re.findall(pat, s)]
>>> print(lst)
[(2014, 1, 24, 8, 10), (2014, 1, 26, 13, 15)]
>>> 
>>> out = list(map(maketime, lst))
>>> print(out)
['2014.01.24 08:10', '2014.01.26 13:15']
>>>
с просмотром



>>> import re
>>> 
>>> def maketime(t):
...     return '{:04}.{:02}.{:02} {:02}:{:02}'.format(*t)
... 
>>> s = """'куча разных букв и цифр': ‘userID’, ‘created’: (2014, 1, 24, 8, 10, 21.0), ‘куча разных букв и цифр’ ‘userID’, ‘created’: (2014, 1, 26, 13, 15, 21.0)"""
>>> 
>>> pat = r'‘created’: \((\d+), (\d+), (\d+), (\d+), (\d+), [\d.]+\)'
>>> 
>>> lst = (map(int, i) for i in re.findall(pat, s))
>>> out = list(map(maketime, lst))
>>> print(out)
['2014.01.24 08:10', '2014.01.26 13:15']
>>>

в datetime можно завернуть, если собираешься проводить вычисления с датами



Отредактировано py.user.next (Фев. 6, 2014 20:26:31)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version