M K Сараванан, эта конкретная проблема с парсингом не так уж и сложна для хороших проблем:
import re
import string
text='''
12 items - Ironing Service 11 Mar 2009 to 10 Apr 2009
Washing service (3 Shirt) 23 Mar 2009
This line does not match
'''
date_pat=re.compile(
r'(\d{1,2}\s+[a-zA-Z]{3}\s+\d{4}(?:\s+to\s+\d{1,2}\s+[a-zA-Z]{3}\s+\d{4})?)')
for line in text.splitlines():
if line:
try:
description,period=map(string.strip,date_pat.split(line)[:2])
print((description,period))
except ValueError:
# The line does not match
pass
выходы
# ('12 items - Ironing Service', '11 Mar 2009 to 10 Apr 2009')
# ('Washing service (3 Shirt)', '23 Mar 2009')
Основной рабочей лошадкой здесь, конечно, является повторный паттерн. Давайте разберем это на части:
\d{1,2}\s+[a-zA-Z]{3}\s+\d{4}
- регулярное выражение для даты, эквивалентное tok_date_in_ddmmmyyyy
. \d{1,2}
соответствует одной или двум цифрам, \s+
соответствует одному или нескольким пробелам, [a-zA-Z]{3}
соответствует 3 буквам и т. Д.
(?:\s+to\s+\d{1,2}\s+[a-zA-Z]{3}\s+\d{4})?
- регулярное выражение, окруженное (?:...)
.
Это указывает на не группирующее регулярное выражение. Используя это, никакая группа (например, match.group (2)) не назначается этому регулярному выражению. Это важно, потому что date_pat.split () возвращает список, в котором каждая группа является членом списка. Подавляя группировку, мы сохраняем весь период 11 Mar 2009 to 10 Apr 2009
вместе. Знак вопроса в конце указывает на то, что этот шаблон может появляться ноль или один раз. Это позволяет регулярному выражению соответствовать обоим
23 Mar 2009
и 11 Mar 2009 to 10 Apr 2009
.
text.splitlines()
разбивает текст на \n
.
date_pat.split('12 items - Ironing Service 11 Mar 2009 to 10 Apr 2009')
разбивает строку в регулярном выражении date_pat. Матч включен в возвращаемый список.
Таким образом, мы получаем:
['12 items - Ironing Service ', '11 Mar 2009 to 10 Apr 2009', '']
map(string.strip,date_pat.split(line)[:2])
подтверждает результат.
Если line
не соответствует date_pat
, то date_pat.split(line)
возвращает [line,]
,
итак
description,period=map(string.strip,date_pat.split(line)[:2])
вызывает ValueError, потому что мы не можем распаковать список с одним элементом в 2-кортеже. Мы ловим это исключение, но просто переходим на следующую строку.