我想检查此字符串模式"name.{j}.name.{i}.param"
是否以"{i}.param"
答案 0 :(得分:5)
执行此测试的最有效方法是使用string match
或regexp
。您也可以使用string last
或string range
并测试它是否相等。
让我们测试一下!
<强>设置强>
% set str "name.{j}.name.{i}.param"
name.{j}.name.{i}.param
% set pat "{i}.param"
{i}.param
string match
% string match *$pat $str
1
% time {string match *$pat $str} 10000
8.0875808 microseconds per iteration
通过删除定时循环外的模式结构进行优化:
% set glob *$pat
*{i}.param
% time {string match $glob $str} 10000
5.4690824000000005 microseconds per iteration
string last
% expr {[string last $pat $str]==[string length $str]-[string length $pat]}
1
% time {expr {[string last $pat $str] == [string length $str]-[string length $pat]}} 10000
10.675282300000001 microseconds per iteration
好的,这太慢了。让我们尝试分解一些计算:
% set len [expr {[string length $str] - [string length $pat]}]
14
% time {expr {[string last $pat $str] == $len}} 10000
6.8803367 microseconds per iteration
% time {expr {[string last $pat $str] == 14}} 10000
6.835114999999999 microseconds per iteration
更快,但不如string match
快。如果模式不存在,则在长输入字符串上较慢。
string range
% time {expr {[string range $str end-[expr {[string length $pat]-1}] end] eq $pat}} 10000
11.9834488 microseconds per iteration
通过分解静态计算再次优化:
% set idx end-[expr {[string length $pat]-1}]
end-8
% time {expr {[string range $str $idx end] eq $pat}} 10000
7.7081886 microseconds per iteration
% time {expr {[string range $str end-8 end] eq $pat}} 10000
7.261692600000001 microseconds per iteration
那回到了球场,并且表现一致。
regexp
请注意,我们需要做一些准备正则表达式的工作,因为它包含元字符但我们想要进行结束锚定匹配。这个准备步骤本身就很昂贵。
% time {regexp [regsub -all {\W} $pat {\\&}]$ $str} 10000
24.428607500000002 microseconds per iteration
0! ü! C! ħ!
让我们考虑RE构建和重新定时:
% set RE [regsub -all {\W} $pat {\\&}]$
\{i\}\.param$
% regexp $RE $str
1
% time {regexp $RE $str} 10000
5.4204058 microseconds per iteration
快速。但我们需要提前完成建设步骤。
虽然使用regexp
速度很快,但由于准备步骤本身很昂贵,因此使用起来确实很棘手。我建议正常使用string match
方法。