正则表达式负面展望未给出期望的结果

时间:2018-05-10 03:40:29

标签: regex pattern-matching negative-lookahead

我有两个字符串,如下所示:

6015603 06/12/2017 06/12/2017 02:45:28 PM - BIL/001347764403/LOAN/NSP CR  20,000.00  8,381.002 S 6156702 06/12/2017 06/12/2017

6015603 06/12/2017 06/12/2017 - BIL/001347764403/LOAN/NSP CR  20,000.00  8,381.002 S 6156702 06/12/2017 06/12/2017

和正则表达式如下:

[0-9]+\s+[0-9]{2}[\/][0-9]{2}[\/][0-9]{4}\s+[0-9]{2}[\/][0-9]{2}[\/][0-9]{4}\s*(?![0-9]{2}[:][0-9]{2}[:][0-9]{2}\s*(AM|PM)).*?(?=([0-9]+\s*[0-9]{2}[\/][0-9]{2}[\/][0-9]{4}+\s+[0-9]{2}[\/][0-9]{2}[\/][0-9]{4})|\\Z)

正如你所看到的,我已经使用了负向前看以避免时间

(?![0-9]{2}[:][0-9]{2}[:][0-9]{2}\s*(AM|PM))

但是当我运行模式匹配时,两个字符串都匹配。我希望忽略第一个字符串。我在做什么错了?

2 个答案:

答案 0 :(得分:1)

我得到了解决方案,我没有在负面展望中包含\ s *。在包括它之后它正在按照需要工作。

错误的是:

\s*(?![0-9]{2}[:][0-9]{2}[:][0-9]{2}\s*(AM|PM))

正确的是:

(?!\s*[0-9]{2}[:][0-9]{2}[:][0-9]{2}\s*(AM|PM))

我从以下主题中获取了答案参考: regex: Why this negative lookahead doesn't work?

答案 1 :(得分:0)

您可以在匹配第一个日期后添加(?!.*?\d{2}:\d{2}:\d{2}\s*[AP]M)否定前瞻:

^\d+\s+\d{2}/\d{2}/\d{4}\s+\d{2}/\d{2}/\d{4}(?!.*?\d{2}:\d{2}:\d{2}\s*[AP]M).*?(?=(\d+\s*\d{2}/\d{2}/\d{4}\s+\d{2}/\d{2}/\d{4})|$)
                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

请参阅regex demo

如果在第一个日期和任何0+字符之后尽可能少地存在与\d{2}:\d{2}:\d{2}\s*[AP]M模式匹配的时间子字符串,那么前瞻将完全失败匹配。

我还添加了字符串/行^锚点的开头,将所有[0-9]替换为\d(更短),[\/]替换为/( Java中的regexp不使用正则表达式分隔符,因此不需要转义/这不是特殊的正则表达式元字符),缩小(AM|PM)[AP]M以减少分组开销,并替换\Z使用$,但如果您的意思是字符串的结尾而不是一行,则可以使用\Z锚点。

请注意,在Java中,您需要转义上面字符串中的每个反斜杠。