Main Content

Square Bracket protection in Tcl

Archive - Originally posted on "The Horse's Mouth" - 2007-10-23 06:23:22 - Graham Ellis

I was writing some string match examples in Tcl yesterday - and had the need to explicitly match square brackets within my string. But I couldn't just write the square brackets into the match string ...

• The square bracket first needed protection from the Tcl parser before it even got to the string match command.

• Then it needed protection within the string match command to prevent it being interpreted as the start of a range.

In both cases, a \ character can be used to provide protection - that's 2 \ characters that I need - but then the \ that protects the [ in the string match itself needs protecting from the command line interpreter, making a total of three protective characters needed. Thus:

  if {[string match *\\[* $saying]} {
    puts WOW!
  }


"Does it have to be that hard?" you ask. No - you can also use { and } to defer the string match pattern, so that it's not interpreted by the command line, thus reducing the number of backslashes needed back down to just the one:

  if {[string match {*\[*} $saying]} {
    puts WOW!
  }


Here's a longer sample program also showing the use of { and ] in a string match to indicate any one character from a range:

foreach saying {"The [world] is round"
    "pie in the sky" "Horse hooves"} {
  puts $saying
  if {[string match *\[ys\] $saying]} {
    puts Y
  }
  if {[string match {*[ys]} $saying]} {
    puts Y
  }
  if {[string match *\\[* $saying]} {
    puts WOW!
  }
  if {[string match {*\[*} $saying]} {
    puts WOW!
  }
  }


and here is how that runs:

Dorothy:~/csr1 grahamellis$ tclsh ll2
The [world] is round
WOW!
WOW!
pie in the sky
Y
Y
Horse hooves
Y
Y
Dorothy:~/csr1 grahamellis$