Regex Tcl中贪婪与非贪婪操作的匹配

Regex Tcl中贪婪与非贪婪操作的匹配,regex,tcl,Regex,Tcl,假设我要将一个文本与以下文本匹配 [ OK - 977613837 bytes ] 我可以用多种方式编写regexp。考虑下面的代码, set length "\[ OK - 977613837 bytes \]" puts $length #can be many ways, I am just keeping 2, to have it for question's sake puts [ regexp -inline {\[\s+OK\s+-\s+\d+\s+bytes\s+\]}

假设我要将一个文本与以下文本匹配

[ OK - 977613837 bytes ] 
我可以用多种方式编写regexp。考虑下面的代码,

set length "\[ OK - 977613837 bytes \]"
puts $length

#can be many ways, I am just keeping 2, to have it for question's sake
puts [ regexp -inline {\[\s+OK\s+-\s+\d+\s+bytes\s+\]} $length ] 
puts [ regexp -inline {\[.*OK.*\d+.*bytes.*\]} $length ]
在这里,两个regexp都用于获取结果,以了解匹配的文本是否可用

假设我不担心子匹配文本,假设文本是一致的(即,在最后一个右方括号之后不会有任何内容)。我之所以说文本将是一致的,是为了避免贪婪运算符获取更多文本

我相信,在这种情况下,在给定的条件下,两者的含义是相同的


问起来可能有点傻,但就执行时间而言,哪个regexp更有效

很难预测什么是最快的RE,特别是当输入集非常有限时。正则表达式可以在开始时很快匹配,但通常很慢,或者很快匹配,但很慢匹配失败,等等。您还必须意识到,捕获任何东西都会减慢引擎的速度,任何回溯都是如此。使用
time
命令进行调查

% set length "\[ OK - 977613837 bytes \]"
[ OK - 977613837 bytes ]
% puts [regexp -inline {\[\s+OK\s+-\s+\d+\s+bytes\s+\]} $length]
{[ OK - 977613837 bytes ]}
% time {regexp -inline {\[\s+OK\s+-\s+\d+\s+bytes\s+\]} $length}
26 microseconds per iteration
% time {regexp -inline {\[\s+OK\s+-\s+\d+\s+bytes\s+\]} $length} 1000
8.996317 microseconds per iteration
% time {regexp -inline {\[\s+OK\s+-\s+\d+\s+bytes\s+\]} $length} 10000
6.5541893 microseconds per iteration
% time {regexp -inline {\[\s+OK\s+-\s+\d+\s+bytes\s+\]} $length} 100000
6.42272296 microseconds per iteration
(请注意,增加迭代次数可以使每次迭代的时间更准确。)

不过,有一些一般性的观点:Tcl缓存编译好的RE,因此连续运行同一个RE几次是很快的。它有几种管理缓存的方法,但是缓存在文本或存储在全局/名称空间变量中的REs中工作得非常好(前提是您不修改变量)


在运行计时之前,请确保您正在使用优化的Tcl构建。调试生成要慢得多。

我建议使用
将[regexp-inline{\[\s+OK\s+\-\s+\d+\s+bytes\s+\]}$length]放入
,因为使用这个正则表达式可以避免回溯。问得好。测试了一下,发现了一些让我吃惊的结果。到目前为止,最快的是使用
{\[\s*OK\s*-\s*\d+\s*bytes\s*\]}
。事实上,
{\[\s*OK\d*\d*\d+\s*bytes\s*\]}
是当前最快的。@Jerry:只有最后一个会匹配很多不是空格的字符串。@Dinesh,我实际上在我对你问题的第二个评论中隐藏了一个链接。尝试在“最快”之后将鼠标悬停在圆点上,您将得到一个链接,其中我计时了5个不同的正则表达式。你也许可以挑一个你喜欢的:)谢谢多纳尔的解释