如何使用Python的正则表达式模块(re
)来确定是否已进行匹配,或者是否可以进行匹配?
我想要一个正则表达式模式,它以正确的顺序搜索单词模式,而不管它们之间是什么。我想要一个函数,如果找到则返回Yes
,如果仍然可以找到匹配则Maybe
,或者如果找不到匹配则No
。我们正在寻找模式One|....|Two|....|Three
,这里有一些例子(注意名称,数量或顺序并不重要,我关心的是三个单词One
,Two
和Three
,其间可接受的字词为John
,Malkovich
,Stamos
和Travolta
。
返回YES:
One|John|Malkovich|Two|John|Stamos|Three|John|Travolta
返回YES:
One|John|Two|John|Three|John
返回YES:
One|Two|Three
返回MAYBE:
One|Two
返回MAYBE:
One
返回NO:
Three|Two|One
我理解这些例子不是密不透风的,所以这就是我为正则表达式得到的所以:
if re.match('One\|(John\||Malkovich\||Stamos\||Travolta\|)*Two\|(John\||Malkovich\||Stamos\||Travolta\|)*Three\|(John\||Malkovich\||Stamos\||Travolta\|)*', 'One|John|Malkovich|Two|John|Stamos|Three|John|Travolta') != None
return 'Yes'
显然,如果模式为Three|Two|One
,上述内容将失败,我们可以返回No
,但如何查看Maybe
案例?我想过嵌套括号,就像这样(注意,未经测试)
if re.match('One\|((John\||Malkovich\||Stamos\||Travolta\|)*Two(\|(John\||Malkovich\||Stamos\||Travolta\|)*Three\|(John\||Malkovich\||Stamos\||Travolta\|)*)*)*', 'One|John|Malkovich|Two|John|Stamos|Three|John|Travolta') != None
return 'Yes'
但我认为这不会做我想做的事。
我实际上并不是在寻找Travoltas
和Malkovichs
(令人震惊,我知道)。我正在匹配inotify模式,例如IN_MOVE
,IN_CREATE
,IN_OPEN
,我正在记录它们并获得数百个,然后我进去然后查找特定模式,例如IN_ACCESS
... IN_OPEN
.... IN_MODIFY
,但在某些情况下我不希望在IN_DELETE
之后IN_OPEN
而在其他情况下我需要Maybe
。我本质上是模式匹配,使用inotify来检测文本编辑器何时疯狂并且他们试图通过执行临时文件交换保存而不是仅修改文件来粉碎程序员灵魂。我不想立即释放这些日志,但我只想在必要时坚持使用它们。 Yes
表示不删除日志。 No
表示执行某些操作然后删除日志,vim
表示不执行任何操作,但仍会删除日志。因为我将为每个程序设置多个规则(即。gedit
v emacs
v {{1}})我想使用一个更易于阅读且更容易编写的正则表达式然后创建一个大量树,或者用户Joel建议,只需用循环覆盖单词
答案 0 :(得分:4)
我不会使用正则表达式。但这绝对是可能的:
regex = re.compile(
r"""^ # Start of string
(?: # Match...
(?: # one of the following:
One() # One (use empty capturing group to indicate match)
| # or
\1Two() # Two if One has matched previously
| # or
\1\2Three() # Three if One and Two have matched previously
| # or
John # any of the other strings
| # etc.
Malkovich
|
Stamos
|
Travolta
) # End of alternation
\|? # followed by optional separator
)* # any number of repeats
$ # until the end of the string.""",
re.VERBOSE)
现在你可以通过检查你是否得到匹配来检查YES和MAYBE:
>>> yes = regex.match("One|John|Malkovich|Two|John|Stamos|Three|John|Travolta")
>>> yes
<_sre.SRE_Match object at 0x0000000001F90620>
>>> maybe = regex.match("One|John|Malkovich|Two|John|Stamos")
>>> maybe
<_sre.SRE_Match object at 0x0000000001F904F0>
您可以通过检查是否所有组都参与了比赛(即不是None
)来区分YES和MAYBE:
>>> yes.groups()
('', '', '')
>>> maybe.groups()
('', '', None)
如果正则表达式根本不匹配,那对你来说就是NO:
>>> no = regex.match("Three|Two|One")
>>> no is None
True
答案 1 :(得分:3)
有些人在面对问题时会想“我知道,我会使用正则表达式”。现在他们有两个问题。 - 杰米·扎温斯基
也许像这样的算法会更合适。这是一些伪代码。
matchlist.current = matchlist.first()
for each word in input
if word = matchlist.current
matchlist.current = matchlist.next() // assuming next returns null if at end of list
else if not allowedlist.contains(word)
return 'No'
if matchlist.current = null // we hit the end of the list
return 'Yes'
return 'Maybe'