我读过所有相关的帖子,也浏览过互联网,但这真的让我很不爽。
我有一些包含约会的短信。
我想捕捉日期,但如果它之前有一个特定的短语。
一个简单的解决方案是在我的RegEx中添加一个负面的外观。
下面是一些示例(使用findall)。
我只想捕捉日期,如果它之前没有短语“截至”。
19-2-11
某事15-4-11
比如29-5-11
以下是我的正则表达式:
(?<!as of )(\d{1,2}-\d{1,2}-\d{2})预期成果:
'19-2-11‘
[]
实际结果:
'19-2-11‘
'9-5-11‘
注意那是9而不是29。如果我在第一种模式中将\d{1,2}更改为\d{2}这样的实体:
bad regex for testing: (?<!as of )(\d{2}-\d{1,2}-\d{2})然后我就得到了我的预期结果。当然,这是没有好处的,因为我想匹配2位数的日子以及单位数字的日子。
显然,我消极的外表比我的约会记录更贪婪,所以它偷了一个数字,结果失败了。我试过每一种方法来纠正我所能想到的贪婪,但我只是不知道如何解决这个问题。
我希望我的约会捕捉与最大的贪婪相匹配,然后我的负面展望被应用。这个是可能的吗?我的问题似乎很好地利用了负面观察,而不是过于复杂。如果必要的话,我相信我可以用另一种方式来完成它,但我想学习如何做到这一点。
如何使Python的负面外观变得不那么贪婪?
发布于 2012-05-02 20:49:12
原因并不是因为放眼望去是贪婪的。这是因为regex引擎试图在它所能找到的任何位置匹配模式。
它一开始通过短语such and such as of 29-5-11成功地匹配(?<!as of ),但没有匹配\d{1,2}。
但是,引擎发现自己位于such and such as of !29-5-11位置(标记为!)。但在这里,它无法与(?<!as of )相匹配。
它将进入下一个位置:such and such as of 2!9-5-11。它成功地匹配了(?<!as of )和\d{1,2}。
如何避免呢?
一般的解决方案是尽可能清晰地制定模式。
在这种情况下,我将在数字前面加上必要的空格或字符串的开头。
(?<!as of)(?:^|\s+)(\d{1,2}-\d{1,2}-\d{2})马克·拜尔斯的解决方案也很好。
我认为理解regex引擎为什么会以这种方式工作并给出不想要的结果是非常重要的。
顺便说一句,如果有两个或更多的空格,我给出的解决方案就不能工作。它不工作,因为第一个位置匹配这里的such and such as of ! 29-5-11与上述模式。
怎样才能避免呢?
不幸的是,Python中的查找不支持量词+或*。
我认为最简单的解决方案是确保在(?:^|\s+)之前没有空格(这意味着所有空格都由(?:^|\s+)直接在任何非空间文本之后使用(如果文本是as of,则终止前进并回溯到下一个开始位置,在搜索文本的下一个位置重新开始搜索)。
re.search(r'(?<!as of)(?<!\s)(?:^|\s+)(\d{1,2}-\d{1,2}-\d{2})','such and such as of 29-5-11').group(1)发布于 2012-05-02 20:27:37
这与贪婪无关。贪婪不会改变正则表达式是否匹配-它只改变执行搜索的顺序。这里的问题是,您的正则表达式需要更具体,以避免不必要的匹配。
要修复它,您可以在匹配之前要求一个单词边界:
(?<!as of )\b(\d{1,2}-\d{1,2}-\d{2})
# ^^ add this发布于 2012-05-02 21:15:37
一个简单的解决方案是在使用regex隔离日期之前丢弃所有与“截至”匹配的行。
https://stackoverflow.com/questions/10421150
复制相似问题