n00b programmer
n00b programmer

Reputation: 2701

TCL regsub isn't working when the expression has [0]

I tried the following code:

set exp {elem[0]}
set temp {elem[0]}

regsub $temp $exp "1" exp

if {$exp} {
    puts "######### 111111111111111 ################"
} else {
    puts "########### 0000000000000000 ############"
}

of course, this is the easiest regsub possible (the words match completely), and still it doesnt work, and no substitution is done. if I write elem instead of elem[0], everything works fine. I tried using {elem[0]}, elem[0], "elem[0]" etc, and none of them worked. Any clue anyone?

Upvotes: 2

Views: 1622

Answers (2)

slebetman
slebetman

Reputation: 113866

This is the easiest regsub possible (the words match completely)

Actually, no, the words don't match. You see, in a regular expression, square brackets have meaning. Your expression {elem[0]} actually mean:

match the sequence of letters 'e'
                  followed by 'l'
                  followed by 'e'
                  followed by 'm'
                  followed by '0' (the character for the number zero)

So it would match the string "elem0" not "elem[0]" since the character after 'm' is not '0'.

What you want is {elem\[0\]} <-- backslash escapes special meaning.

Read the manual for tcl's regular expression syntax, re_syntax, for more info on how regular expressions work in tcl.

Upvotes: 6

glenn jackman
glenn jackman

Reputation: 246764

In addition to @slebetman's answer, if your want any special characters in your regular expression to be treated like plain text, there is special syntax for that:

set word {abd[0]}
set regex $word
regexp $regex $word        ;# => returns 0, did not match
regexp "(?q)$regex" $word  ;# => returns 1, matched

That (?q) marker must be the first part of the RE.

Also, if you're really just comparing literal strings, consider the simpler if {$str1 eq $str2} ... or the glob-style matching of [string match]

Upvotes: 3

Related Questions