Home > Net >  Get multiple matches with tcl regexp
Get multiple matches with tcl regexp

Time:12-07

How do I get all the matches in tcl using regexp command? For example I have a string as following

set line "foo \"aaa\"zz bar \"aaa:ccc\" ccc"
puts $line
foo "aaa"zz bar "aaa:ccc" ccc

I now want to get aaa and aaa:ccc. There could be any number of such matches. I tried

regexp -all -inline {"(.*)"} $line 
{"aaa"zz bar "aaa:ccc"} {aaa"zz bar "aaa:ccc}

But as seen this didn't work. What's the right way to get multiple matches and match everything within double quotes?

CodePudding user response:

You can capture all between two quotes with "([^"]*)" pattern. When using the pattern with regexp -all -inline:

set matches [regexp -all -inline {"([^"]*)"} $line]

you will get all overall match values and all the captured substrings.

You will have to post-process the matches in order to get the final list of captures:

set line "foo \"aaa\"zz bar \"aaa:ccc\" ccc"
set matches [regexp -all -inline {"([^"]*)"} $line]
set res {}
foreach {match capture} $matches {
    lappend res $capture
}
puts $res

See the online Tcl demo.

Output:

aaa aaa:ccc

CodePudding user response:

An alternate method to extract the quoted strings is:

set unquoted [lmap quoted [regexp -all -inline {".*?"} $line] {string trim $quoted {"}}]

Or, split the string using quote as the delimiter, and take every second field.

set unquoted [lmap {a b} [split $line {"}] {set b}]

That gives you a trailing empty element since this split invocation results in a list with an odd number of elements.

  • Related