RegEx для захвата дат с определенным шаблоном - PullRequest
1 голос
/ 24 мая 2019

Я пытаюсь извлечь данные из нескольких PDF-файлов. Существует одна точка данных, относящаяся к датам, где строки до даты варьируются в разных PDF-файлах. Я проверил, работают ли отдельные операторы регулярных выражений, однако, когда я пытаюсь объединить операторы регулярных выражений в один оператор в цикле for, я не извлекаю даты. Вот строки, которые я пытаюсь сопоставить с моим кодом для их отдельных операторов регулярных выражений, которые извлекают информацию о дате после «ДАТЫ РОЖДЕНИЯ»:

DATE OF BIRTHDAY\n01/11/2011
date_of_birthday1 = re.search('(?<=DATE OF BIRTHDAY \\n)(.*)', img).groups()

DATE OF BIRTHDAY\n\n02/14/2015
date_of_birthday2 = re.search('(?<=DATE OF BIRTHDAY \\n\\n)(.*)', img).groups()

DATE OF BIRTHDAY GIRL \n\ni : Pll i ii\ni \n\nPll 05/07/2018
date_of_birthday3 = re.search('(?<=DATE OF BIRTHDAY GIRL \n\ni : Pll i ii\ni \n\nPll)(.*)', img).groups()

Я пытаюсь объединить эти операторы регулярных выражений в оператор или, чтобы я мог использовать их в цикле for, например:

date_of_birthdays = re.search('(?<=DATE OF BIRTHDAY\\n\\n)(.*)|(?<=DATE OF BIRTHDAY\\n)(.*)|(?<=DATE OF BIRTHDAY GIRL \n\ni : Pll i ii\ni \n\nPll)(.*)', img).groups

Мой ожидаемый результат -

df['Birthdays'] = date_of_birthdays

, который будет выглядеть так:

df = pd.DataFrame({"Birthdays": ['01/11/2011', '02/14/2015', '05/07/2018']})
df

Однако я не могу получить какую-либо информацию о дате. Мысли о том, что я здесь делаю не так?

1 Ответ

1 голос
/ 24 мая 2019

Это работает

>>> import re
>>> re.findall(
...  r"(?:DATE[ ]OF[ ]BIRTHDAY)(?:\\n(?:\\n)?|[ ]GIRL[ ]\\n\\ni[ ]:[ ]Pll[ ]i[ ]ii\\ni[ ]\\n\\nPll[ ])?(.*)",
...  (
...  r'DATE OF BIRTHDAY\n01/11/2011' + "\n"
...  r'DATE OF BIRTHDAY\n\n02/14/2015' + "\n"
...  r'DATE OF BIRTHDAY GIRL \n\ni : Pll i ii\ni \n\nPll 05/07/2018' + "\n"
...  ))
['01/11/2011', '02/14/2015', '05/07/2018']
>>>

Расширение регулярных выражений

 (?: DATE [ ] OF [ ] BIRTHDAY )

 (?:
      \\ n 
      (?: \\ n )?
   |  [ ] GIRL [ ] \\ n \\ ni [ ] : [ ] Pll [ ] i [ ] ii \\ n i [ ] \\ n \\ n Pll [ ] 
 )?
 ( .* )                        # (1)

Просто Справедливое предупреждение , выражения с утверждениями о взгляде
представляют проблемув этих двух чередованиях:

   (?<= DATE [ ] OF [ ] BIRTHDAY \\ n \\ n )
   ( .* )                        # (1)
|  (?<= DATE [ ] OF [ ] BIRTHDAY \\ n )
   ( .* )                        # (2)  

Трудно визуализировать, поэтому я просто выйду и скажу это:
захватит группу 1 (первое чередование) будетникогда не совпадать !!

Причина в том, что сначала всегда проверяется более короткое расстояние в обратном направлении.
Поскольку .* дает возможность сопоставления, более короткое расстояние с одним литералом \n
всегда будет совпадатьпервый.

Вы можете исправить это, принудив , а не к совпадению, добавив (?!\\n) вот так

   (?<= DATE [ ] OF [ ] BIRTHDAY \\ n \\ n )
   ( .* )                        # (1)
|  (?<= DATE [ ] OF [ ] BIRTHDAY \\ n )
   (?! \\ n )
   ( .* )                        # (2)  

Ну, это не так, вотнекоторые тесты рассматриваемых способов
(что на самом деле не идеальный способ сделать это)

Regex1:   (?:DATE[ ]OF[ ]BIRTHDAY)(?:\\n(?:\\n)?|[ ]GIRL[ ]\\n\\ni[ ]:[ ]Pll[ ]i[ ]ii\\ni[ ]\\n\\nPll[ ])?(.*)
Options:  < none >
Completed iterations:   50  /  50     ( x 1000 )
Matches found per iteration:   3
Elapsed Time:    0.29 s,   294.80 ms,   294801 µs
Matches per sec:   508,817


Regex2:   (?:(?<=DATE[ ]OF[ ]BIRTHDAY\\n\\n)|(?<=DATE[ ]OF[ ]BIRTHDAY\\n)(?!\\n)|(?<=DATE[ ]OF[ ]BIRTHDAY[ ]GIRL[ ]\\n\\ni[ ]:[ ]Pll[ ]i[ ]ii\\ni[ ]\\n\\nPll[ ]))(.*)
Options:  < none >
Completed iterations:   50  /  50     ( x 1000 )
Matches found per iteration:   3
Elapsed Time:    2.27 s,   2268.42 ms,   2268417 µs
Matches per sec:   66,125


Regex3:   (?<=DATE[ ]OF[ ]BIRTHDAY\\n\\n)(.*)|(?<=DATE[ ]OF[ ]BIRTHDAY\\n)(?!\\n)(.*)|(?<=DATE[ ]OF[ ]BIRTHDAY[ ]GIRL[ ]\\n\\ni[ ]:[ ]Pll[ ]i[ ]ii\\ni[ ]\\n\\nPll[ ])(.*)
Options:  < none >
Completed iterations:   50  /  50     ( x 1000 )
Matches found per iteration:   3
Elapsed Time:    2.76 s,   2760.81 ms,   2760809 µs
Matches per sec:   54,331
...