问题:
我如何使用 Python 的正则表达式模块 (re) 来确定是否已经进行了匹配,或者是否可以进行潜在的匹配?
详情:
我想要一个正则表达式模式,它以正确的顺序搜索单词模式,而不管它们之间是什么。我想要一个函数,如果找到则返回 Yes,如果仍然可以找到匹配项则返回 Maybe,如果找不到匹配项则返回 No。我们正在寻找模式 One|....|Two|....|Three,这里有一些示例(注意名称、它们的数量或它们的顺序并不重要,我关心的是One、Two和Three这三个词,中间可接受的词是John、Malkovich、Stamos 和 Travolta)。
返回是:
One|John|Malkovich|Two|John|Stamos|Three|John|Travolta
返回是:
One|John|Two|John|Three|John
返回是:
One|Two|Three
可能会返回:
One|Two
可能会返回:
One
返回NO:
Three|Two|One
我知道这些例子不是无懈可击的,所以这是我让正则表达式获得 YES 的条件:
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(我知道这令人震惊)。我正在匹配 IN_MOVE、IN_CREATE、IN_OPEN 等 inotify 模式,我正在记录它们并获得数百个,然后我进入然后寻找特定的模式,例如 IN_ACCESS...IN_OPEN....IN_MODIFY,但在某些情况下我不想IN_OPEN 之后的 IN_DELETE 和其他我做的。我本质上是使用 inotify 进行模式匹配来检测何时文本编辑器变得疯狂,并且他们试图通过执行临时文件交换保存而不是仅仅修改文件来粉碎程序员的灵魂。我不想立即释放这些日志,但我只想在必要时保留它们。 Maybe 表示不要删除日志。 Yes 表示执行某些操作然后删除日志,No 表示不执行任何操作但仍然删除日志。因为我将为每个程序设置多个规则(即 vim v gedit v emacs),所以我想使用一个正则表达式人类可读且更容易编写,然后创建一个巨大的树,或作为用户 Joel建议,只是用循环遍历单词
请您参考如下方法:
我不会为此使用正则表达式。但这绝对有可能:
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 = regex.match("Three|Two|One")
>>> no is None
True
