sashang
sashang

Reputation: 12194

How to match a colon after a close bracket

Why does the following not match the :

expect {
    timeout {puts timedout\n}
    \[1\]: {puts matched\n}
}


> expect test.tcl
[1]:
timedout

If I change it and remove the colon the match works:

expect { timeout {puts timedout\n} \[1\] {puts matched\n} }

$ expect test.tcl [1] matched

Or if I get rid of the 1st bracket

expect { timeout {puts timedout\n} 1\]: {puts matched\n} } then it matches:

$ expect test.tcl 1]: matched

Upvotes: 2

Views: 238

Answers (2)

Dinesh
Dinesh

Reputation: 16428

It is not the problem with :, but with [.

The [ is special to both Tcl and the Expect pattern matcher so it is particularly messy. To match a literal [, you have to backslash once from Tcl and then again so that it is not treated as a range during pattern matching. The first backslash, of course, has to be backslashed to prevent it from turning the next backslash into a literal backslash!

expect "\\\[" ; #matches literal '['

So, your code should be,

expect {
    timeout {puts timedout\n}
    \\\[1]: {puts matched\n}
}

You can prefix the ] with a backslash if it makes you feel good, but it is not necessary. Since there is no matching left-hand bracket to be matched within the double-quoted string, nothing special happens with the right-hand bracket. It stands for itself and is passed on to the Expect command, where it is then interpreted as the end of the range.

The next set of examples shows the behavior of [ as a pattern preceded by differing numbers of backslashes. If the [ is not prefixed by a backslash, Tcl interprets whatever follows as a command. For these examples, imagine that there is a procedure named XY that returns the string n*w.

expect" [XY]" ; # matches n followed by anything
expect "\[XY]" ; # matches X or Y
expect "\\[XY]" ; # matches n followed by anything followed by w
expect "\\\[XY]" ; # matches [XYl
expect "\\\\[XY]" ; # matches \ followed by n followed ...
expect "\\\\\[XY]" ; # matches sequence of \ and X or Y

The \\[XY] case deserves close scrutiny. Tcl interprets the first backslash to mean that the second is a literal character. Tcl then produces n*w as the result of the XY command. The pattern matcher ultimately sees the four character string n*w. The pattern matcher interprets this in the usual way. The backslash indicates that the n is to be matched literally (which it would even without the backslash since the n is not special to the pattern matcher).

Source : Exploring Expect

Upvotes: 3

Eugeniu Rosca
Eugeniu Rosca

Reputation: 5305

The patterns that worked for me:

  • -exact {[1]:}
  • -exact "\[1]:"
  • {\[1]:}
  • "\\\[1]:"

Upvotes: 1

Related Questions