Извлечение нескольких форматов даты через регулярное выражение в Python - PullRequest
3 голосов
/ 06 марта 2019

Я пытаюсь извлечь дату из текста в Python. Это возможные тексты и шаблоны дат.

"Auction details: 14 December 2016, Pukekohe Park"
"Auction details: 17 Feb 2017, Gold Sacs Road"
"Auction details: Wednesday 27 Apr 1:00 p.m. (On site)(2016)"
"Auction details: Wednesday 27 Apr 1:00 p.m. (In Rooms - 923 Whangaa Rd, Man)(2016)"
"Auction details: Wed 27 Apr 2:00 p.m., 48 Viaduct Harbour Ave, Auckland, (2016)"
"Auction details: November 16 Wednesday 2:00pm at 48 Viaduct Harbour Ave, Auckland(2016)"
"Auction details: Thursday, 28th February '19"
"Auction details: Friday, 1st February '19"

Это то, что я написал до сих пор,

mon = ' (?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|(Nov|Dec)(?:ember)?) '
day1 = r'\d{1,2}'
day_test = r'\d{1,2}(?:th)|\d{1,2}(?:st)' 
year1 = r'\d{4}'
year2 = r'\(\d{4}\)'
dummy = r'.*'

Это фиксирует случаи 1,2.

match = re.search(day1 + mon + year1, "Auction details: 14 December 2016, Pukekohe Park")
print match.group()

Это несколько отражает случай 3,4,5. Но он печатает все из текста, поэтому в приведенном ниже случае я хочу 25 ноября 2016 года, но шаблон регулярного выражения дает мне 25 ноября 3:00 вечера. (На сайте) (2016).

Итак, вопрос 1: Как получить только дату здесь?

match = re.search(day1 + mon + dummy + year2, "Friday 25 Nov 3:00 p.m. (On Site)(2016)")
print match.group()

Вопрос 2: Точно так же, как захватить случаи 6,7 и 8 ?? Какое регулярное выражение должно быть для этого?

Если нет, есть ли какой-нибудь другой лучший способ получения даты из этих форматов?

1 Ответ

3 голосов
/ 06 марта 2019

Вы можете попробовать

((?:(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|(?:Nov|Dec)(?:ember)?)\s+\d{1,2}(?:st|nd|rd|th)?|\d{1,2}(?:st|nd|rd|th)?\s+(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|(?:Nov|Dec)(?:ember)?)))(?:.*(\b\d{2}(?:\d{2})?\b))?

См. Демонстрационную версию regex .

Примечание. Я сделал все группы в блоках регулярных выражений незаписываемыми ((Nov|Dec) ->(?:Nov|Dec)), добавлен (?:st|nd|rd|th)? необязательный шаблон цифр группа за днем, изменен шаблон соответствия года на \b\d{2}(?:\d{2})?\b, чтобы он соответствовал только 4- или 2-значным блокам как целым словам, и была создана группа альтернатив для учета датгде день предшествует месяцу и наоборот.

День и месяц фиксируются в группе 1, а год включается в группу 2, поэтому в результате получается соединение обоих.

ПРИМЕЧАНИЕ : в случае, если вам нужно сопоставить годы более безопасным способом, вы можете уточнить точную диаграмму года.Например, если вы хотите избежать совпадения 4- или 2-значных целых слов после :, добавьте отрицательный вид сзади:

year1 = r'\b(?<!:)\d{2}(?:\d{2})?\b'
            ^^^^^^

Кроме того, вы можете добавить границы слов вокруг всего шаблона, чтобыполное совпадение слов.

Вот демо Python :

import re
mon = r'(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|(?:Nov|Dec)(?:ember)?)'
day1 = r'\d{1,2}(?:st|nd|rd|th)?'
year1 = r'\b\d{2}(?:\d{2})?\b'
dummy = r'.*'

rx = r"((?:{smon}\s+{sday1}|{sday1}\s+{smon}))(?:{sdummy}({syear1}))?".format(smon=mon, sday1=day1, sdummy=dummy, syear1=year1)
# Or, try this if a partial number before a date is parsed as day:
# rx = r"\b((?:{smon}\s+{sday1}|{sday1}\s+{smon}))(?:{sdummy}({syear1}))?".format(smon=mon, sday1=day1, sdummy=dummy, syear1=year1)
strs = ["Auction details: 14 December 2016, Pukekohe Park","Auction details: 17 Feb 2017, Gold Sacs Road","Auction details: Wednesday 27 Apr 1:00 p.m. (On site)(2016)","Auction details: Wednesday 27 Apr 1:00 p.m. (In Rooms - 923 Whangaa Rd, Man)(2016)","Auction details: Wed 27 Apr 2:00 p.m., 48 Viaduct Harbour Ave, Auckland, (2016)","Auction details: November 16 Wednesday 2:00pm at 48 Viaduct Harbour Ave, Auckland(2016)","Auction details: Thursday, 28th February '19","Auction details: Friday, 1st February '19","Friday 25 Nov 3:00 p.m. (On Site)(2016)"]  
for s in strs:
    print(s)
    m = re.search(rx, s)
    if m:
        print("{} {}".format(m.group(1), m.group(2)))
    else:
        print("NO MATCH")

Вывод:

Auction details: 14 December 2016, Pukekohe Park
14 December 2016
Auction details: 17 Feb 2017, Gold Sacs Road
17 Feb 2017
Auction details: Wednesday 27 Apr 1:00 p.m. (On site)(2016)
27 Apr 2016
Auction details: Wednesday 27 Apr 1:00 p.m. (In Rooms - 923 Whangaa Rd, Man)(2016)
27 Apr 2016
Auction details: Wed 27 Apr 2:00 p.m., 48 Viaduct Harbour Ave, Auckland, (2016)
27 Apr 2016
Auction details: November 16 Wednesday 2:00pm at 48 Viaduct Harbour Ave, Auckland(2016)
November 16 2016
Auction details: Thursday, 28th February '19
28th February 19
Auction details: Friday, 1st February '19
1st February 19
Friday 25 Nov 3:00 p.m. (On Site)(2016)
25 Nov 2016
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...