Regex 在最后一个匹配开始而不是在第一个匹配结束的惰性正则表达式

Regex 在最后一个匹配开始而不是在第一个匹配结束的惰性正则表达式,regex,Regex,我试图从半结构化文本中提取数据,这是一封由制表符分隔的表组成的电子邮件。用户在每个表的顶部输入了时间戳,并在表中列出了我要查找的安全标识符 目标是提取correctsecurity和correctsecurity所在表顶部的时间戳 例如 10:00 AM not it not it 9:00 AM not it correctsecurity ..应该返回9:00 AM correct security。然而,我当前的正则表达式返回的是10:00am correctsecurity,意思是正

我试图从半结构化文本中提取数据,这是一封由制表符分隔的表组成的电子邮件。用户在每个表的顶部输入了时间戳,并在表中列出了我要查找的安全标识符

目标是提取
correctsecurity
correctsecurity
所在表顶部的时间戳

例如

10:00 AM
not it
not it

9:00 AM
not it
correctsecurity
..应该返回
9:00 AM correct security
。然而,我当前的正则表达式返回的是
10:00am correctsecurity
,意思是正确的项目,但不是正确的时间

这是我到目前为止的正则表达式:

((1[0-2]|[0-9]):[0-5][0-9](\s?(AM | PM))?)(?:(.*\n)+(correctsecurity)

请注意,最后一部分
correctsecurity
是根据其他标准动态创建的,因此即使我在这个问题中提供了实际项目,它也不会有什么帮助(因为它是许多项目中的一个),为简单起见,请假设
correctsecurity
正是我要寻找的项目


最后,我在VBA中执行此操作,因此,如果不使用长正则表达式,解决整个问题可能会更容易,因此请随意推荐非正则表达式解决方案。

您可以使用负前瞻解决此问题:

a((?!a).)*correctsecurity

其中A是你想要开始比赛的模式,而不想在比赛中间加入。

适用于您的特定需求:

\d*:\d* [AP]M((?!\d*:\d* [AP]M).)*correctsecurity
别忘了让点匹配线断开

我假设VBA使用VBScript正则表达式方言,需要进行以下修改:

\d*:\d* [AP]M((?!\d*:\d* [AP]M)[\s\S])*correctsecurity

您可以使用负前瞻解决此问题:

a((?!a).)*correctsecurity

其中A是你想要开始比赛的模式,而不想在比赛中间加入。

适用于您的特定需求:

\d*:\d* [AP]M((?!\d*:\d* [AP]M).)*correctsecurity
别忘了让点匹配线断开

我假设VBA使用VBScript正则表达式方言,需要进行以下修改:

\d*:\d* [AP]M((?!\d*:\d* [AP]M)[\s\S])*correctsecurity

要解决主要问题,只需将正则表达式的中心部分更改为不接受空行:

*\n
->
+\n

然后在中间部分之前添加一个换行锚点
\n
,以避免跳过
AM | PM
部分:

因此,您的正则表达式将是:


可选优化 您可以删除许多不需要的组,并为换行符
(?:\r\n?|\n)
添加通用多操作系统正则表达式:


要解决主要问题,只需将正则表达式的中心部分更改为不接受空行:

*\n
->
+\n

然后在中间部分之前添加一个换行锚点
\n
,以避免跳过
AM | PM
部分:

因此,您的正则表达式将是:


可选优化 您可以删除许多不需要的组,并为换行符
(?:\r\n?|\n)
添加通用多操作系统正则表达式: