用于捕获具有特定模式的日期的正则表达式

2024-06-14 06:06:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图从几个PDF中提取数据。有一个与日期相关的数据点,其中日期之前的字符串在某些PDF中有所不同。我检查了各个regex语句是否正常工作,但是,当我尝试在for循环中将regex语句组合成一个语句时,并没有提取日期。以下是我试图与代码匹配的字符串,这些字符串用于在“生日”之后提取日期信息的单个regex语句:

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()

我试图将这些regex语句组合成or语句,以便在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

但是,我无法提取任何日期信息。想想我做错了什么?你知道吗


Tags: of字符串reimgsearchdate语句regex
1条回答
网友
1楼 · 发布于 2024-06-14 06:06:28

这很管用

>>> 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)

只是一个警告而已,这个表达式是用lookbehind assessions表示的
在这两种备选方案中提出一个问题:

   (?<= 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

相关问题 更多 >