我正在写一个小的java程序进行一些数据库清理,当我们需要从大块文本中提取日期时,它们出现在与某些关键字相同的句子中,并且我得到一些奇怪的行为,我想不通。例如,以下正则表达式:
"(?=.*(due|submit|deadline)[^\\d]*)"
+ "(january|february|march|april|may|june|july|august|september|october|november|december)"
+ "\\s*(0?[1-9]|[12][0-9]|3[01])(th|rd|nd|st)*,*\\s*((19|20)\\d\\d)"
不匹配:
“必须在2013年6月19日星期三中午12点之前提交,届时将会被阅读。”
虽然关键字"submit"
发生在日期之前。如果我拿出前瞻,字符串匹配。谁能看到我做错了什么?谢谢!
答案 0 :(得分:1)
似乎你忘记了前瞻是零宽度,这意味着正则表达式光标将被设置在前瞻开始检查其状态的地方。这意味着零件匹配
+ "(january|february|march|april|may|june|july|august|september|october|november|december)"
+ "\\s*(0?[1-9]|[12][0-9]|3[01])(th|rd|nd|st)*,*\\s*((19|20)\\d\\d)";
需要在先行开始检查的地方之后存在。
要解决此问题,您需要在.*?
之前添加(january|...
,以便通过前瞻和匹配(例如due
之前的位置)来检查几个月的位置。
另外,要避免多次使用前瞻,只需在启动后添加^
即可在字符串启动后立即查找匹配项。
所以你的最终正则表达式看起来像
String regex = "^(?=.*(due|submit|deadline)[^\\d]*)"
+ ".*?(january|february|march|april|may|june|july|august|september|october|november|december)"
+ "\\s*(0?[1-9]|[12][0-9]|3[01])(th|rd|nd|st)*,*\\s*((19|20)\\d\\d)";
实际上我不确定你为什么甚至使用预测。不会像
那样 String regex = "(due|submit|deadline).*?"
+ "(january|february|march|april|may|june|july|august|september|october|november|december)"
+ "\\s*(0?[1-9]|[12][0-9]|3[01])(th|rd|nd|st)*,*\\s*((19|20)\\d\\d)";
也做你想做的事情?