在 Tcl 中,我怎样才能删除左边的所有零但右边的零应该保留?
In Tcl how can I remove all zeroes to the left but the zeroes to the right should remain?
伙计们!我运行遇到了一个我自己无法解决的问题。
由于数字“08”和“09”不能像其他数字(01,02,03,04 等...)一样读取,因此必须在语言 Tcl.
我找不到删除所有[我说全部是因为同一行上有多个]前导零的方法,但右边的那个必须保持不变。
对于已经完全熟悉Tcl/Tk语言的人来说,这可能听起来很简单。但是对于我来说,谁开始寻找更多关于 Tcl / Tk 的信息,我在互联网上阅读了很多 material,包括这个 https: // whosebug.com/questions/2110864/handling-numbers-with-leading-zeros-in-tcl#2111822
所以没有什么可以告诉我如何在一次扫描中消除所有前导零。
I need you to give me a return like this: 2:9:10
我需要这个以便稍后使用 expr
[算术表达式] 命令处理结果。
在这个例子中,它只是删除了一个前导零:
set time {02:09:10}
puts [regsub {^0*(.+)} $time {}]
# Return: 2:09:10
有谁能给我那个力量的朋友吗?!我现在很感激。
您只匹配字符串开头的 0
,您还需要在每个 :
之后匹配。
puts [regsub -all {(^|:)0*([^:])} $time {}]
组 (^|:)
匹配字符串的开头或冒号。
0+ 匹配一个或多个零。替换为组匹配 </code>,
否则冒号会丢失。当然,使用 <code>-all
完成所有操作
目标字符串中的匹配项。
% set z 02:09:10
02:09:10
% regsub -all {(^|:)0+} $z {} x
2
% puts $x
2:9:10
%
编辑:正如 Barmar 指出的那样,这会将 :00 更改为空字符串。
更好的正则表达式可能是:
regsub -all {(^|:)0} $z {} x
这只会删除一个前导 0。
一般来说,最好使用scan $str %d
将可能带有前导零的十进制数转换为其实际值。
但在你的情况下这也有效(对我来说似乎比之前给出的答案更简单并且不依赖于分隔符是冒号):
regsub -all {0*(\d+)} $time {}
这将删除任意数量的前导零,但不会 trim 00 变成空字符串。尾随零也不会受到影响。
regsub -all {0*(\d+)} {0003:000:1000} {}
=> 3:0:1000
scan
命令在这里很有用,可以从该字符串中提取三个 十进制 数字:
% set time {02:09:10}
02:09:10
% scan $time {%d:%d:%d} h m s
3
% puts [list $h $m $s]
2 9 10
这里有一些棘手的边缘情况。具体来说,字符串 02:09:10:1001:00
覆盖了关键的(包括中间的零,只有零)。我们可以使用一个替换命令来完成这项工作:
regsub -all {\m0+(?=\d)} $str {}
(这使用单词开始锚点和前瞻约束。)
不过,我更倾向于使用其他工具来做这类事情。例如,有时候,解析它们最好使用 scan
:
set time "02:09:10"
scan $time "%d:%d:%d" h m s
或者,根据发生的情况,clock scan
(它也处理日期,使其在某些情况下更有用,而在其他情况下则更少)。
伙计们!我运行遇到了一个我自己无法解决的问题。
由于数字“08”和“09”不能像其他数字(01,02,03,04 等...)一样读取,因此必须在语言 Tcl.
我找不到删除所有[我说全部是因为同一行上有多个]前导零的方法,但右边的那个必须保持不变。
对于已经完全熟悉Tcl/Tk语言的人来说,这可能听起来很简单。但是对于我来说,谁开始寻找更多关于 Tcl / Tk 的信息,我在互联网上阅读了很多 material,包括这个 https: // whosebug.com/questions/2110864/handling-numbers-with-leading-zeros-in-tcl#2111822 所以没有什么可以告诉我如何在一次扫描中消除所有前导零。
I need you to give me a return like this: 2:9:10
我需要这个以便稍后使用 expr
[算术表达式] 命令处理结果。
在这个例子中,它只是删除了一个前导零:
set time {02:09:10}
puts [regsub {^0*(.+)} $time {}]
# Return: 2:09:10
有谁能给我那个力量的朋友吗?!我现在很感激。
您只匹配字符串开头的 0
,您还需要在每个 :
之后匹配。
puts [regsub -all {(^|:)0*([^:])} $time {}]
组 (^|:)
匹配字符串的开头或冒号。
0+ 匹配一个或多个零。替换为组匹配 </code>,
否则冒号会丢失。当然,使用 <code>-all
完成所有操作
目标字符串中的匹配项。
% set z 02:09:10
02:09:10
% regsub -all {(^|:)0+} $z {} x
2
% puts $x
2:9:10
%
编辑:正如 Barmar 指出的那样,这会将 :00 更改为空字符串。 更好的正则表达式可能是:
regsub -all {(^|:)0} $z {} x
这只会删除一个前导 0。
一般来说,最好使用scan $str %d
将可能带有前导零的十进制数转换为其实际值。
但在你的情况下这也有效(对我来说似乎比之前给出的答案更简单并且不依赖于分隔符是冒号):
regsub -all {0*(\d+)} $time {}
这将删除任意数量的前导零,但不会 trim 00 变成空字符串。尾随零也不会受到影响。
regsub -all {0*(\d+)} {0003:000:1000} {}
=> 3:0:1000
scan
命令在这里很有用,可以从该字符串中提取三个 十进制 数字:
% set time {02:09:10}
02:09:10
% scan $time {%d:%d:%d} h m s
3
% puts [list $h $m $s]
2 9 10
这里有一些棘手的边缘情况。具体来说,字符串 02:09:10:1001:00
覆盖了关键的(包括中间的零,只有零)。我们可以使用一个替换命令来完成这项工作:
regsub -all {\m0+(?=\d)} $str {}
(这使用单词开始锚点和前瞻约束。)
不过,我更倾向于使用其他工具来做这类事情。例如,有时候,解析它们最好使用 scan
:
set time "02:09:10"
scan $time "%d:%d:%d" h m s
或者,根据发生的情况,clock scan
(它也处理日期,使其在某些情况下更有用,而在其他情况下则更少)。