Найти - Пользователи
Полная версия: Парсиинг. Регулярка. datetime
Начало » Python для новичков » Парсиинг. Регулярка. datetime
1
zahar
Всем привет. Друзья помогите с такой проблемой.
Например на входе имеется строка вида:
'куча разных букв и цифр': ‘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']

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

ЗЫЖ Текст в квадратных скобках не отображается пришлось его заключить в теги хтмл
PanovSergey
регуляркой дергайте всю строку целиком (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)
Как то так Думаю строчку вы уже на компоненты разобрали. Только проверьте что для все вариантов данных работает.
zahar
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

PanovSergey
'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)
zahar
PanovSergey
s =
>>> datetime.datetime(*)
Ну ё-маё конечно. спс огромное
zahar
PanovSergey
21.
Давайте добьем до конца, один момент, а если значение s будет:
s = ['2014', '1', '24', '3', '27', '2014', '1', '24', '3', '34', '2014', '1', '24', '6', '37']
те надо получить три даты и времени.

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

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

И вообще я не понимаю зачем здесь вообще регулярка? У вас ‘created’: однозначно определяет где в строке искомая дата. Я бы тупо по ней строку засплитил и дело с концом
zahar
Дата одна, но время разное. Да и дата может меняться
Ну да ладно, информацию для размышления получил, буду пробовать. Еще раз спасибо за помощь
PanovSergey
Дата одна, но время разное.
Конечно имеется виду по одному набору типа (2014, 1, 24, 8, 10, 21.0), простите некорректно выразился
py.user.next
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 можно завернуть, если собираешься проводить вычисления с датами
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB