Совпадение символов и цифр фиксированной длины и одного вхождения в Python - PullRequest
2 голосов
/ 18 сентября 2019

У меня есть список в Python со значениями

['JUL_2018', 'AUG_2018', 'SEP_2018', 'OCT_2018', 'NOV_2018', 'DEC_2018', 'JAN_2019', 'FEB_2019', 'MAR_2019', 'APR_2019', 'MAY_2019', 'JUN_2019', 'MAT_YA_1', 'MAT_TY_1', 'YTD_YA_1', 'YTD_TY_1', 'L3M_YA_1', 'L1M_YA_1']

Я хочу сопоставлять только те строки, где длина равна 8 и есть 3 символа перед подчеркиванием и 4 цифры после подчеркивания, поэтому я исключаю значения, которые не требуются.Меня интересуют только значения MMM_YYYY из приведенного выше списка.

Попробовал ниже, и я не могу отфильтровать такие значения, как YTD_TY_1 с несколькими подчеркиваниями.

        for c in col_headers:
            d= (re.match('^(?=.*\d)(?=.*[A-Z0-9])[A-Z_0-9\d]{8}$',c))
            if d:
                data_period.append(d[0])

Ответы [ 3 ]

0 голосов
/ 18 сентября 2019

Вместо того, чтобы использовать для этого регулярное выражение, вы должны просто попытаться проанализировать его как дату:

from datetime import datetime
date_fmt = "%b_%Y"
for c in col_headers:
    try:
        d = datetime.strptime(c, date_fmt)
        data_period.append(c) # Or just save the datetime object directly
    except ValueError:
        pass
0 голосов
/ 18 сентября 2019

Часть этого кода, которая фактически выполняет сопоставление в вашем решении, состоит в следующем:

[A-Z_0-9\d]{8}

Проблема в том, что вы просите найти ровно 8 символов, которые включают A-Z, _, 0-9 и \d.Теперь \d эквивалентно 0-9, поэтому вы можете устранить это, но это не решает всей проблемы, проблема в том, что вы заключили все решение в скобки [].По сути, ваша строка будет соответствовать всему, что имеет длину 8 символов и включает в себя вышеуказанные символы, а именно: A_19_KJ9

Что вам нужно сделать, это указать, что вы хотите ровно 3 A-Z символа, а затем один _, затем 4 \d, см. ниже:

[A-Z]{3}_\d{4}

Это будет соответствовать чему угодно с точно 3 A-Z символами, затем одним _, затем 4 \d (любой числовой цифрой)

Для лучшего понимания регулярных выражений, я рекомендую вам использовать онлайн-инструмент, например regex101

0 голосов
/ 18 сентября 2019

Обновление: на основе наблюдения @ WiktorStribiżew, что re.match не требует полного совпадения строк в Python

Используемое мной регулярное выражение основано на том, который @dvo предоставил вкомментарий:

import re

REGEX = '^[A-Z]{3}_[0-9]{4}$'
col_headers = ['JUL_2018', 'AUG_2018', 'SEP_2018', 'OCT_2018', 'NOV_2018', 'DEC_2018', 'JAN_2019', 'FEB_2019', 'MAR_2019', 'APR_2019', 'MAY_2019', 'JUN_2019', 'MAT_YA_1', 'MAT_TY_1', 'YTD_YA_1', 'YTD_TY_1', 'L3M_YA_1', 'L1M_YA_1']
regex = re.compile(REGEX)
data_period = list(filter(regex.search, col_headers))

Еще раз, основываясь на комментарии, сделанном @ WiktorStribiżew, если вы не хотите сопоставлять что-либо с "SXX_0012" или "XYZ_0000", вы должны использовать регулярное выражение, которое он предоставил вкомментарий:

REGEX = r'^(?:JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)-[0-9]{4}$'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...