【问题标题】:What's the most efficient way of checking whether a string ends with a certain character with TCL?用 TCL 检查字符串是否以某个字符结尾的最有效方法是什么?
【发布时间】:2015-12-24 02:42:54
【问题描述】:

我想检查这个字符串模式"name.{j}.name.{i}.param"是否以"{i}.param"结尾

【问题讨论】:

  • regexp "{i}.param$" "name.{j}.name.{i}.param"?
  • string match "*{i}.param" $string -- tcl.tk/man/tcl8.6/TclCmd/string.htm -- 但我认为你问的问题不正确。
  • 这与您上一个问题没有太大不同。你为什么不退后一步,想想描述你真正想做的事情。

标签: tcl


【解决方案1】:

进行此测试的最有效技术是使用string matchregexp。您还可以使用 string laststring 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

哦!你! 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 方法。

【讨论】:

  • 请注意,如果我在一个过程中执行它们,时间会更快,因为它允许优化变量访问,但是从中获得良好的时间是相当困难的,并且模式时间可能会相似。
  • string matchregexp 时间的相似性也并非巧合:“足够简单”的正则表达式会自动转换为 glob。
猜你喜欢
  • 2010-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-07
  • 2014-12-20
  • 2012-09-03
  • 1970-01-01
  • 2013-08-23
相关资源
最近更新 更多