【发布时间】:2017-08-15 01:58:40
【问题描述】:
尝试学习正则表达式,尽管这里有一些很棒的帖子和一个 regEx 网站的链接,但我有一个案例我试图摆脱纯粹的固执,无法产生我正在寻找的匹配。要理解它,请考虑以下代码,它允许我们传入一个字符串列表和一个模式,并找出该模式是匹配列表中的所有项目还是一个都不匹配:
import re
def matchNone(pattern, lst):
return not any([re.search(pattern, i) for i in lst])
def matchAll(pattern, lst):
return all([re.search(pattern, i) for i in lst])
为了帮助调试,这个简单的代码允许我们将 _test 添加到函数调用中,然后查看传递给 any() 或 all() 函数的内容,最终返回结果:
def matchAll_test(pattern, lst):
return [re.search(pattern, i) for i in lst]
def matchNone_test(pattern, lst):
return ([re.search(pattern, i) for i in lst])
此模式和列表从matchAll() 生成True:
wordPattern = "^[cfdrp]an$"
matchAll(wordPattern, ['can', 'fan', 'dan', 'ran', 'pan']) # True
表面上的这种模式似乎与matchNone() 一起工作,我们正在努力扭转这种模式:
wordPattern = "^[^cfdrp]an|[cfdrp](^an)$"
matchNone(wordPattern, ['can', 'fan', 'dan', 'ran', 'pan']) # True
它像我们希望的那样返回True。但是,这种模式的真正反转将返回 False 以获得一个值列表,其中没有一个与我们的原始列表 ['can', 'fan', 'dan', 'ran', 'pan'] 等效,而不管我们传递给它的其他内容。 (即“匹配除这 5 个单词之外的任何内容”)
在测试该列表中单词的哪些更改会为我们提供False 时,我们很快发现该模式并不像最初出现的那样成功。如果是这样,matchNone() 在上述列表之外的任何内容上都会失败。
这些排列有助于发现我的模式测试的缺点:
["something unrelated", "p", "xan", "dax", "ccan", "dann", "ra"]
在我对上面的探索中,我尝试了其他排列方式以及原始列表,使用_test 版本的函数并在原始单词上一次更改一个字母,或者修改一个术语或添加一个术语从上面的排列。
如果有人能找到我原始模式的真正反面,我很乐意看到它,以便我可以从中学习。
为了帮助您进行调查:
这种模式也适用于所有单词的matchAll(),但我似乎也无法创建它的逆模式:"^(can|fan|dan|ran|pan)$"
感谢您为此付出的任何时间。我希望在这里找到一位发现错误并能提出正确解决方案的 regEx 大师。
【问题讨论】:
-
inverse/reverse 是什么意思?
-
(^an)并不意味着“除了an”。在字符类之外,^匹配字符串的开头(在 MULTILINE 模式下也是行的开头)。 -
即使它确实的意思是“除了
an”,你仍然不会正确地反转你的正则表达式。 -
在这里回复所有的cmets。虽然第一个模式成功匹配了列表中的 5 个单词,但我正在寻找的“reverse”或“inverse”(但正在寻找单词)是一个匹配传递给它的所有内容的模式,除了我们样本中的 5 个单词。关于“^”上的 cmets,在各种 regEx 站点和我正在学习的课程中,这个字符有两个上下文:在模式的最开始它意味着模式的开始,但是在 [] 内部,可能在 () 内部或放在图案的中间,意思是“不是这个”。 . .
-
我的模式测试都到了一半,但是当我通过一些给定的测试用例时,它们都失败了,所以它们不是真正的“反转”或原始的,并且在匹配的目标上失败,除了列表中有什么。如前所述,围绕这个用例可能还有其他方法,但找到我正在寻找的正则表达式等价性将有助于我掌握它的语法以及我在尝试的模式中看到的一些令人困惑的结果。跨度>