In Tcl how can I remove all zeroes to the left but the zeroes to the right should remain?

1.1k Views Asked by At

Folks! I ran into a problem that I can't solve by myself.

Since the numbers "08" and "09" cannot be read like the others (01,02,03,04, etc ...) and must be treated separately in the language Tcl.

I can't find a way to remove all [I say ALL because there are more than one on the same line] the leading zeros except the one on the right, which must remain intact.

It may sound simple to those who are already thoroughly familiar with the Tcl / Tk language. But for me, who started out and am looking for more information about Tcl / Tk, I read a lot of material on the internet, including this https: // stackoverflow.com/questions/2110864/handling-numbers-with-leading-zeros-in-tcl#2111822 So nothing to show me how to do this in one sweep eliminating all leading zeros.

I need you to give me a return like this: 2:9:10

I need this to later manipulate the result with the expr [arithmetic expression] command.

In this example it just removes a single leading zero:

set time {02:09:10}
puts [regsub {^0*(.+)} $time {\1}]
# Return: 2:09:10

If anyone can give me that strength friend?! I'm grateful right now.

5

There are 5 best solutions below

2
On BEST ANSWER

The group (^|:) matches either the beginning of the string or a colon. 0+ matches one or more zeros. Replace with the group match \1, otherwise the colons get lost. And of course, use -all to do all of the matches in the target string.

% set z 02:09:10
02:09:10
% regsub -all {(^|:)0+} $z {\1} x
2
% puts $x
2:9:10
% 

Edit: As Barmar points out, this will change :00 to an empty string. A better regex might be:

regsub -all {(^|:)0} $z {\1} x

This will only remove a single leading 0.

1
On

In general it is best to use scan $str %d to convert a decimal number with possible leading zeroes to its actual value.

But in your case this will also work (and seems simpler to me than the answers given earlier and doesn't rely on the separator being a colon):

regsub -all {0*(\d+)} $time {\1}

This will remove any number of leading zeroes, but doesn't trim 00 down to an empty string. Also trailing zeroes will not be affected.

regsub -all {0*(\d+)} {0003:000:1000} {\1} => 3:0:1000

0
On

the scan command is useful here to extract three decimal numbers out of that string:

% 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
3
On

There are a few tricky edge cases here. Specifically, the string 02:09:10:1001:00 covers the key ones (including middle zeroes, only zeroes). We can use a single substitution command to do the work:

regsub -all {\m0+(?=\d)} $str {}

(This uses a word start anchor and lookahead constraint.)

However, I would be more inclined to use other tools for this sort of thing. For times, for example, parsing them is better done with scan:

set time "02:09:10"
scan $time "%d:%d:%d" h m s

Or, depending on what is going on, clock scan (which handles dates as well, making it more useful in some cases and less in others).

1
On

You're only matching the 0 at the beginning of the string, you need to match after each : as well.

puts [regsub -all {(^|:)0*([^:])} $time {\1\2}]