Rectangle 27 0

Accessing my capture group in regex pattern matching in Expect to a variable?


$ expect <<END
spawn sh -c {echo foo; echo "this is a line 2 4 5 6"; echo bar}
exp_internal 1
expect -re {(?n)^this\sis\sa\sline((?:\s\d)+)\r?$}
END
fconfigure
spawn sh -c echo foo; echo "this is a line 2 4 5 6"; echo bar
Gate keeper glob pattern for '(?n)^this\sis\sa\sline((?:\s\d)+)\r?$' is 'this?is?a?line*'. Activating booster.

expect: does "" (spawn_id exp4) match regular expression "(?n)^this\sis\sa\sline((?:\s\d)+)\r?$"? Gate "this?is?a?line*"? gate=no
foo

expect: does "foo\r\n" (spawn_id exp4) match regular expression "(?n)^this\sis\sa\sline((?:\s\d)+)\r?$"? Gate "this?is?a?line*"? gate=no
this is a line 2 4 5 6
bar

expect: does "foo\r\nthis is a line 2 4 5 6\r\nbar\r\n" (spawn_id exp4) match regular expression "(?n)^this\sis\sa\sline((?:\s\d)+)\r?$"? Gate "this?is?a?line*"? gate=yes re=yes
expect: set expect_out(0,string) "this is a line 2 4 5 6\r"
expect: set expect_out(1,string) " 2 4 5 6"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "foo\r\nthis is a line 2 4 5 6\r"

And what's the (?n) at the beginning?

Follow the link I provided in the answer.

I don't know about expect's "gate" -- it looks like it's trying to convert the regex into a glob pattern, but in this case that's not helpful at all, since you need the regex capturing parentheses.

If you enable newline sensitive matching in the regular expression and take the carriage return into account, you may find this regular expression works: (?n)^this\sis\sa\sline((?:\s\d)+)\r?$

That worked perfectly for me. Thanks! What's a "Gate" in Expect?

The issue is that you are including line anchors ^ and $ in your regex. The string you're trying to match is clearly a multi-line string, but Tcl's default matching treats newlines just like a regular character. Another complicating factor is that Tcl considers a newline to be \n but expect is using \r\n as the line terminator.

Note
Rectangle 27 0

Accessing my capture group in regex pattern matching in Expect to a variable?


$ expect <<END
spawn sh -c {echo foo; echo "this is a line 2 4 5 6"; echo bar}
exp_internal 1
expect -re {(?n)^this\sis\sa\sline((?:\s\d)+)\r?$}
END
fconfigure
spawn sh -c echo foo; echo "this is a line 2 4 5 6"; echo bar
Gate keeper glob pattern for '(?n)^this\sis\sa\sline((?:\s\d)+)\r?$' is 'this?is?a?line*'. Activating booster.

expect: does "" (spawn_id exp4) match regular expression "(?n)^this\sis\sa\sline((?:\s\d)+)\r?$"? Gate "this?is?a?line*"? gate=no
foo

expect: does "foo\r\n" (spawn_id exp4) match regular expression "(?n)^this\sis\sa\sline((?:\s\d)+)\r?$"? Gate "this?is?a?line*"? gate=no
this is a line 2 4 5 6
bar

expect: does "foo\r\nthis is a line 2 4 5 6\r\nbar\r\n" (spawn_id exp4) match regular expression "(?n)^this\sis\sa\sline((?:\s\d)+)\r?$"? Gate "this?is?a?line*"? gate=yes re=yes
expect: set expect_out(0,string) "this is a line 2 4 5 6\r"
expect: set expect_out(1,string) " 2 4 5 6"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "foo\r\nthis is a line 2 4 5 6\r"

And what's the (?n) at the beginning?

Follow the link I provided in the answer.

I don't know about expect's "gate" -- it looks like it's trying to convert the regex into a glob pattern, but in this case that's not helpful at all, since you need the regex capturing parentheses.

If you enable newline sensitive matching in the regular expression and take the carriage return into account, you may find this regular expression works: (?n)^this\sis\sa\sline((?:\s\d)+)\r?$

That worked perfectly for me. Thanks! What's a "Gate" in Expect?

The issue is that you are including line anchors ^ and $ in your regex. The string you're trying to match is clearly a multi-line string, but Tcl's default matching treats newlines just like a regular character. Another complicating factor is that Tcl considers a newline to be \n but expect is using \r\n as the line terminator.

Note