Search code examples
tclbackslashregsub

Adding an additional backslash to elements of TCL list


I have a list which looks like:

list1 = {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....}

When I operate on the element of the list one by one using a foreach loop:

`foreach ele $list1 {
puts "$ele
}`

I get the following output:

a.b.c.d a.bb.ccd[0] a.bb.ccd[1]

Observe that, the backslash goes missing(due to the tcl language flow).

In order to preserve the same, I want to add an extra backslash to all the elements of list1 having an existing backslash.

I tried :

regsub -all {\} $list1 {\\} list1 (Also tried the double quotes instead of braces and other possible trials).

Nothing seems to work.

Is there a way to make sure the $ele preserves the backslash characters inside the foreach loop, as I need the elements with the exact same characters for further processing.

P.S. Beginner in using regexp/regsub


Solution

  • If your input data has backslashes in it like that that you wish to preserve, you need to use a little extra work when converting that data to a Tcl list or Tcl will simply assume that you were using the backslashes as conventional Tcl metacharacters. There's a few ways to do it; here's my personal favourite as it is logically selecting exactly the chars that we want (the non-empty sequences of non-whitespaces):

    set input {a.b.c.d a.bb.ccd\[0\] a.bb.ccd\[1\] ....}
    set items [regexp -all -inline {\S+} $input]
    foreach item $items {
        puts $item
    }
    

    As you can see from the output:

    a.b.c.d
    a.bb.ccd\[0\]
    a.bb.ccd\[1\]
    ....
    

    this keeps the backslashes exactly. (Also, yes, I quite like regular expressions. Especially very simple ones like this.)