请参阅此简单的正则表达式代码:
puts [ regexp -inline {^\-\-\S+?=\S+} "--tox=9.0" ]
输出结果为:
>--tox=9
似乎第二个\ S +非贪婪!只匹配1个字符
在PERL中,人们可以看到结果如我所料,见1行输出:
perl -e '"--tox=9.0" =~/(^\-\-\S+?=\S+)/ ; print "${1}\n"'
--tox=9.0
如何在Tcl中获取Perl行为?
答案 0 :(得分:5)
这是一项固有的功能' Tcl的正则表达式实现。例如,below来自Henry Spencer(即使不是全部Tcl&#39的正则表达式工作,我也相信)
很难想出一个完全令人满意的 混合贪婪正则表达式行为的定义。 Perl并没有尝试:Perl"规范"是一个描述 实施,一种涉及的固有的低性能方法 一次尝试一场比赛。对于许多人来说这是不能令人满意的 原因,尤其是它只需要几页文本 形容它。 (该实现及其描述很遥远, 我之前的一个正则表达式包的后代变异,所以我分享 一些责任归咎于此。)
当所有量词都贪婪时,Tcl 8.2正则表达式匹配 最长的匹配(如POSIX标准中所规定的那样) 正则表达式定义)。当所有人都不贪婪时,它就会匹配 最短的比赛。这些令人满意的陈述都不是 Perl的确如此。
麻烦的是,编写泛化是非常非常困难的 那些涵盖混合贪婪正则表达式的陈述 - 什么是适当的,与实现无关的定义 混合贪婪正则表达式应匹配 - 并使它们成为现实 做"人们的期望"。我试过了。我还在努力。没有运气 远。
Tcl 8.2 regexp中的规则,基本上给出了整个正则表达式 基于其子表达式的长/短偏好是我最好的 到目前为止提出来了。代码准确地实现了它们。我同意 他们没有达到真正想要的水平。它比它更棘手 外观。
基本上,混合贪婪和非贪婪量词的表达式会影响实现的简单性和性能。因此,实现使得第一个类型'量词的传递给所有其他量词。
换句话说,如果第一个量词是贪婪的,那么所有其他量词都会贪婪。如果第一个是非贪婪的,那么所有其他人都不会贪婪。因此,您不能强制Tcl正则表达式像Perl正则表达式那样工作(或者您可以通过exec
并使用perl的bash命令版本,但我对此并不熟悉。)
我建议使用否定的类和/或锚点而不是非贪婪的。
由于我不知道你问题的确切背景,我不会提供另一种正则表达式,因为这取决于这是否真的是你想要匹配的整个字符串。
答案 1 :(得分:3)
Tcl正则表达式引擎是一个自动机理论引擎而不是基于堆栈的引擎,所以它有一个非常不同的方法来匹配混合贪婪RE。特别是,对于你所谈论的那种RE,这将被解释为完全不贪婪。
解决此问题的最简单方法是使用不同的RE。请注意\S
只是[^\s]
的简写,我们可以执行此操作(从第一部分中排除=
):
puts [ regexp -inline {^--[^\s=]+=\S+} "--tox=9.0" ]
(我还将\-
更改为-
,因为它不是Tcl RE中的特殊字符。)
答案 2 :(得分:2)
答案可以找到here:
不幸的是,答案是得到Perl给出的相同答案, 你必须使用Perl的精确正则表达式实现。
在您的情况下,我会使用两个锚^
和$
:
puts [ regexp -inline {^\-\-\S+?=\S+$} "--tox=9.0" ]
结果是:--tox=9.0