2015-12-11 12 views
5

Mam następujący kod pasujące datyKorzystanie Python i regex wyodrębnić różne formaty dat

import re 
date_reg_exp2 = re.compile(r'\d{2}([-/.])(\d{2}|[a-zA-Z]{3})\1(\d{4}|\d{2})|\w{3}\s\d{2}[,.]\s\d{4}') 
matches_list = date_reg_exp2.findall("23-SEP-2015 and 23-09-2015 and 23-09-15 and Sep 23, 2015") 
print matches_list 

Wyjście Spodziewam jest

["23-SEP-2015","23-09-2015","23-09-15","Sep 23, 2015"] 

Co otrzymuję jest:

[('-', 'SEP', '2015'), ('-', '09', '2015'), ('-', '09', '15'), ('', '', '')] 

Proszę sprawdzić link do regexhere.

+1

myślę Twoja pierwsza '(' może być w złym miejscu - dwie pierwsze cyfry nie są przechwytywane, pierwszy rzeczą, którą powiedziałeś, aby ją uchwycić, jest sekwencja '[- /.]' –

+2

Naprawdę trudno jest to zrobić za pomocą regex ... a po prostu użyj '' 23-SEP-2015 i 23-09-2015 oraz 23-09-15 i 23 września 2015 ".split (" i ")" w tym przypadku? –

+0

W tym przypadku działa, ale ciąg wejściowy nie jest faktycznie oddzielony przez 'i'. Może to być 'Ten ciąg znaków to 23-09-2015 i może być również czymś'. Potrzebuję meczu z napisem '['23 -09-2015 ']' –

Odpowiedz

2

Problem polega na tym, że re.findall zwraca tylko przechwycone teksty, wykluczając Grupę 0 (cały proces dopasowania). Ponieważ trzeba cały mecz (grupa 0), wystarczy użyć re.finditer pobrać wartości group():

matches_list = [x.group() for x in date_reg_exp2.finditer("23-SEP-2015 and 23-09-2015 and 23-09-15 and Sep 23, 2015")] 

Zobacz IDEONE demo

re.findall(pattern, string, flags=0)
zwrotu wszystkich nie zachodzą na mecze wzór w ciągu, jako listę ciągów znaków ... Jeśli jedna lub więcej grup jest obecnych we wzorcu, zwraca listę grup; będzie to lista krotek, jeśli wzorzec zawiera więcej niż jedną grupę.

re.finditer(pattern, string, flags=0)
zwrócić iterator otrzymując MatchObject przykłady nad wszystkimi nienakładające się dopasowania do RE wzór g.

2

Można spróbować tego regex

date_reg_exp2 = re.compile(r'(\d{2}(/|-|\.)\w{3}(/|-|\.)\d{4})|([a-zA-Z]{3}\s\d{2}(,|-|\.|,)?\s\d{4})|(\d{2}(/|-|\.)\d{2}(/|-|\.)\d+)') 

Następnie użyj re.finditer()

for m in re.finditer(date_reg_exp2,"23-SEP-2015 and 23-09-2015 and 23-09-15 and Sep 23, 2015"): 
print m.group() 

wyjście będzie

23-SEP-2015
23-09-2015
23-09-15
wrz 23, 2015

+0

Twój regex przechwytuje również coś takiego (czego nie potrzebuję) - '55.123.4567'. Również '/' mówi "Unescaped Forward Slash". Więc myślę, że musisz użyć '\ /'. –

+0

Myślę, że '.' nie występuje w twoich datach, więc nie musi być zawarte w regex i'/'możesz użyć' \/' –

+0

W przykładzie podanym powyżej -' .' nie występuje, ale w czasie rzeczywistym występuje dużo '.' (co najmniej w moim przypadku). –

0

spróbować

# The first (\d{2}-([A-Z]{3}|\d{2})-(\d{4}|\d{2})) group tries to match the first three types of dates 
# rest will match the last type 
dates = "23-SEP-2015 and 23-09-2015 and 23-09-15 and Sep 23, 2015" 
for x in re.finditer('((\d{2}-([A-Z]{3}|\d{2})-(\d{4}|\d{2}))|([a-zA-Z]{3}\s\d{1,2},\s\d{4}))', dates): 
    print x.group(1)