Python Regex Capture Знаки после пробела и дефиса - PullRequest
0 голосов
/ 21 апреля 2020

Это должно быть просто, но мне трудно понять, как захватить часть "-0400" временной метки, показанной ниже.

2020-04-21 23: 59: 59.999-0400

Любая помощь будет принята с благодарностью. Я знаю, что мне нужно пройти курс регулярных выражений sh.

Ответы [ 3 ]

1 голос
/ 22 апреля 2020

Я попытаюсь дать ответ, используя библиотеку re.

Я разбил каждый раздел на отдельные строки, чтобы вы могли видеть, что происходит, но вы можете легко хранить все это в одном линия. Добавление флага re.X позволяет создавать подробные шаблоны.

По сути, я пометил все части объекта datetime, и вы можете использовать re.search().group("name of group here"), чтобы выделить вашу переменную.

import re

dt_neg_value = "2020-04-21 23:59:59.999-0400" # Negative UTC
dt_pos_value = "2020-04-21 23:59:59.999+0400" # Positive UTC
dt_london = "2020-04-21 23:59:59.999+00:00" # Zero UTC + colon separator

dt_pat = r"""
    (?P<yr>\d{4})-      # year.  This looks for four numbers.
    (?P<mth>\d{2})-     # month.  This looks for two numbers.
    (?P<dy>\d{2})\s     # day of month.  This looks for two numbers.
    (?P<hh>\d{1,2})     # hour of day.  This looks for one or two numbers.
    :(?P<mm>\d{1,2})    # minute of hour.  This looks for one or two numbers.
    :(?P<nn>\d{1,2})    # second of minute.  This looks for three numbers.
    \.(?P<ms>\d{3})     # millisecond of second.  We have to escape the period so that it doesn't capture a character.
    (?P<utc_off>.?\d+(:\d*)?)  # utc offset. The '-?' part means that a hyphen is optional. This accounts for +/-00:00, as well
    """

# We'll use re.search passing our patter, variable, and the re.X flag.
# Then we can just call out what we want. I've used `utc_off` to indicate UTC offset.

In[0]: re.search(dt_pat, dt_neg_value, re.X).group("utc_off")
Out[0]: '-0400'

In[1]: re.search(dt_pat, dt_pos_value, re.X).group("utc_off")
Out[1]: '+0400'

In[2]: re.search(dt_pat, dt_london, re.X).group("utc_off")
Out[2]: '+00:00'

Если вы амбициозны, вы можете использовать re.findall() с теми же аргументами и просто выбрать то, что вы хотите по индексу.

In[1]: re.findall(dt_pat, dt_neg_value, re.X)
Out[1]: [('2020', '04', '21', '23', '59', '59', '999', '-0400')]

Или re.search() без суеты:

In[2]: re.search(dt_pat, dt_neg_value, re.X).groups()
Out[2]: ('2020', '04', '21', '23', '59', '59', '999', '-0400')

Наконец, чтобы сохранить порядок, попробуйте re.match.groupdict()

In[3]: re.match(dt_pat, dt_neg_value, re.X).groupdict()
Out[3]: {'yr': '2020',
    'mth': '04',
    'dy': '21',
    'hh': '23',
    'mm': '59',
    'nn': '59',
    'ms': '999',
    'utc_off': '-0400'}

EDIT : обновлен, чтобы учесть отрицательный UT C и включение двоеточия .

0 голосов
/ 22 апреля 2020

Я бы порекомендовал работать с модулем datetime, так как у вас есть дата и время.
Вы ищете смещение UT C, чтобы вы могли использовать этот метод и делить на один час, чтобы получить результат в часах.

import datetime as dt

s = '2020-04-21 23:59:59.999-0400'
adt = dt.datetime.strptime(s,'%Y-%m-%d %H:%M:%S.%f%z')

adt.utcoffset() / dt.timedelta(hours=1)
-4.0

Если хотите, можете обернуть это в функцию:

def utc_offset_hours(s,strptime_str='%Y-%m-%d %H:%M:%S.%f%z'): 
    adt = dt.datetime.strptime(s,strptime_str) 
    return adt.utcoffset() / dt.timedelta(hours=1) 

Пример:

In [82]: utc_offset_hours('2020-04-21 23:59:59.999-0400')
Out[82]: -4.0
0 голосов
/ 22 апреля 2020

Почему регулярное выражение? Предполагая, что формат вашей строки всегда именно такой, ваша часть часового пояса всегда начинается с индекса 23, поэтому:

x = '2020-04-21 23:59:59.999-0400'
print(x[23:]) 

должно делать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...