Извлечение дат в разных форматах с использованием регулярных выражений и их сортировка – панды

Я новичок в разработке текста, и мне нужно извлечь даты из файла * .txt и отсортировать их. Даты между предложениями (каждая строка) и их формат могут быть следующими:

04/20/2009; 04/20/09; 4/20/09; 4/3/09 Mar-20-2009; Mar 20, 2009; March 20, 2009; Mar. 20, 2009; Mar 20 2009; 20 Mar 2009; 20 March 2009; 20 Mar. 2009; 20 March, 2009 Mar 20th, 2009; Mar 21st, 2009; Mar 22nd, 2009 Feb 2009; Sep 2009; Oct 2010 6/2008; 12/2009 2009; 2010 

Если день отсутствует, рассмотрите 1-й и если месяц отсутствует, рассмотрите январь.

Моя идея состоит в том, чтобы извлечь все даты и преобразовать их в формат mm / dd / yyyy. Однако я немного сомневаюсь в том, как найти и заменить патернов. Это то, что я сделал:

 import pandas as pd doc = [] with open('dates.txt') as file: for line in file: doc.append(line) df = pd.Series(doc) df2 = pd.DataFrame(df,columns=['text']) def myfunc(x): if len(x)==4: x = '01/01/'+x else: if not re.search('/',x): example = re.sub('[-]','/',x) terms = re.split('/',x) if (len(terms)==2): if len(terms[-1])==2: x = '01/'+terms[0]+'/19'+terms[-1] else: x = '01/'+terms[0]+'/'+terms[-1] elif len(terms[-1])==2: x = terms[0].zfill(2)+'/'+terms[1].zfill(2)+'/19'+terms[-1] return x df2['text'] = df2.text.str.replace(r'(((?:\d+[/-])?\d+[/-]\d+)|\d{4})', lambda x: myfunc(x.groups('Date')[0])) 

Я сделал это только для формата числовых дат. Но я немного смущен, как это сделать с alfanumerical датами.

Я знаю, это грубый код, но это именно то, что я получил.

Я думаю, что это одно из заданий на интеллектуальную обработку курсора. Ну, вы можете использовать регулярное выражение и извлечь, чтобы получить решение. date.txt, т.е.

 doc = [] with open('dates.txt') as file: for line in file: doc.append(line) df = pd.Series(doc) def date_sorter(): # Get the dates in the form of words one = df.str.extract(r'((?:\d{,2}\s)?(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[az]*(?:-|\.|\s|,)\s?\d{,2}[az]*(?:-|,|\s)?\s?\d{2,4})') # Get the dates in the form of numbers two = df.str.extract(r'((?:\d{1,2})(?:(?:\/|-)\d{1,2})(?:(?:\/|-)\d{2,4}))') # Get the dates where there is no days ie only month and year three = df.str.extract(r'((?:\d{1,2}(?:-|\/))?\d{4})') #Convert the dates to datatime and by filling the nans in two and three. Replace month name because of spelling mistake in the text file. dates = pd.to_datetime(one.fillna(two).fillna(three).replace('Decemeber','December',regex=True).replace('Janaury','January',regex=True)) return pd.Series(dates.sort_values()) date_sorter() 

Вывод:

 9 1971-04-10
 84 1971-05-18
 2 1971-07-08
 53 1971-07-11
 28 1971-09-12
 474 1972-01-01
 153 1972-01-13
 13 1972-01-26
 129 1972-05-06
 98 1972-05-13
 111 1972-06-10
 225 1972-06-15
 31 1972-07-20
 171 1972-10-04
 191 1972-11-30
 486 1973-01-01
 335 1973-02-01
 415 1973-02-01
 36 1973-02-14
 405 1973-03-01
 323 1973-03-01
 422 1973-04-01
 375 1973-06-01
 380 1973-07-01
 345 1973-10-01
 57 1973-12-01
 481 1974-01-01
 436 1974-02-01
 104 1974-02-24
 299 1974-03-01

Если вы хотите вернуть только индекс, return pd.Series(dates.sort_values().index)

Разбор первого регулярного выражения

  # ?: Нехватывающая группа 

 ((?: \ d {, 2} \ s)? # Две группы цифр. `?` относятся к предыдущему маркеру или группе. Здесь цифры 2 или 1 и пробел происходят один или несколько раз.  

  (?: Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec] [az] * # Слова в группе, заканчивающиеся на любые буквы `[]`, происходящие сколько угодно раз ( `*`). 

  (?: - | \. | \ s |,) # Соответствие шаблону -,., space 

  \ S?  # (`?` здесь подразумевается только пробел, то есть предыдущий токен)

  \ d {, 2} [az] * # меньше или равно двум цифрам с любым количеством букв в конце (`*`).  (Например: может быть 1, 13, 22, янв., Декабрь и т. Д.). 

  (?: - |, | \ s)? # Символы - /, / пробел могут возникать один раз и могут не произойти из-за `?` в конце

  \ S?  # пробел может возникнуть или вообще не произойти (максимум 1) (`?` здесь он относится только к пространству)

  \ d {2,4}) # Символьная цифра, которая равна 2 или 4   

Надеюсь, поможет.