2

I have a string xxxxxxx-s12345ab7_0_0_xx2.log and need to have an output like AB700_xx2 in TCL.

ab will be the delimiter and need to extract from ab to . (including ab) and also have to remove only the first two underscores.

Tried string trim, string trimleft and string trimright, but not much use. Is there anything like string split in TCL?

2
  • 1
    Can you explain the structure of the string? Is the ab delimiter always the same? Are the 7, 0, 0 always single digits? Is the x an any character placeholder? Commented Oct 21, 2013 at 8:32
  • 1
    string trim* isn't the right tool for this job, and string split is just called split Commented Oct 21, 2013 at 8:53

3 Answers 3

4

The first stage is to extract the basic relevant substring; the easiest way to do that is actually with a regular expression:

set inputString "xxxxxxx-s12345ab7_0_0_xx2.log"

if {![regexp {ab[^.]+} $inputString extracted]} {
    error "didn't match!"
}
puts "got $extracted"
# ===> got ab7_0_0_xx2

Then, we want to get rid of those nasty underscores with string map:

set final [string map {"_" ""} $extracted]
puts "got $final"
# ===> ab700xx2

Hmm, not quite what we wanted! We wanted to keep the last underscore and to up-case the first part.

set pieces [split $extracted "_"]
set final [string toupper [join [lrange $pieces 0 2] ""]]_[join [lrange $pieces 3 end] "_"]
puts "got $final"
# ===> got AB700_xx2

(The split command divides a string up into “records” by an optional record specifier — which defaults to any whitespace character — that we can then manipulate easily with list operations. The join command does the reverse, but here I'm using an empty record specifier on one half which makes everything be concatenated. I think you can guess what the string toupper and lrange commands do…)

Sign up to request clarification or add additional context in comments.

1 Comment

I would do regsub -all {_(\d)} $extracted {\1} final to remove the "inner" underscores, give or take unspoken requirements.
0
set a "xxxxxxx-s12345ab7_0_0_xx2.log"
set a [split $a ""]
set trig 0
set extract ""
for {set i 0} {$i < [llength $a]} {incr i} {
    if {"ab" eq "[lindex $a $i][lindex $a [expr $i+1]]"} {
        set trig 1
    }
    if {$trig == 1} {
        append extract [lindex $a $i]
    }
}

set extract "[string toupper [join [lrange [split [lindex [split $extract .] 0] _] 0 end-1] ""]]_[lindex [split [lindex [split $extract .] 0] _] end]"

puts $extract

Comments

0

Only regexp is enough to do the trick.

Set string "xxxxxxx-s12345ab7_0_0_xx2.log"

regexp {(ab)(.*)_(.*)_(.*)_(.*)\\.} $string -> s1 s2 s3 s4 s5

Set rstring "$s1$s2$s3$s4\_$s5"

Puts $rstring

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.