尝试学习正则表达式,尽管这里有一些很棒的帖子和链接到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])
此模式和列表从True
生成matchAll()
:
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大师,并提出正确的解决方案。
答案 0 :(得分:2)
我希望我理解你的问题。这是我找到的解决方案:
^(?:[^cfdrp].*|[cfdrp][^a].*|[cfdrp]a[^n].*|.{4,}|.{0,2})$
[^cfdrp].*
:如果文字不是以c,f,d,r或p开头而不是匹配[cfdrp][^a].*
:文字以c,f,d,r或p开头:如果第二个字符不是a,则匹配[cfdrp]a[^n].*
:文字以[cfdrp]a
开头:匹配第三个字符不是n。.{4,}
:匹配超过3个字符的任何内容.{0,2}
:匹配0,1或2个字符的任何内容等于:
^(?:[^cfdrp].*|.[^a].*|..[^n].*|.{4,}|.{0,2})$
答案 1 :(得分:1)
您要做的是找到补充。为任何正则表达式执行此操作是一个难题。没有内置补充正则表达式。
PPCG上有一个开放challenge来执行此操作。一个comment解释了难度:
这是可能的,但是疯狂乏味。您需要将正则表达式解析为NFA(例如Thompson算法),将NFA转换为DFA(powerset构造),完成DFA,找到补码,然后将DFA转换为RE(例如Brzozowski&#39 ; s方法)。即比编写完整的RE引擎稍微难一点!
有些Python库将从正则表达式转换(原始规范指的是"常规语言",它只有文字,"或",和&# 34;明星" - 比你想到[more info here]的正则表达式类型简单到NFA,DFA,补充它,并将其转换回来。这很复杂。
这是一个相关的SO问题:Finding the complement of a DFA?
总之,找到原始正则表达式的结果要简单得多,然后使用布尔否定。