Substring extraction in TCL

2019-08-20 17:51发布

问题:

I'm trying to extract a sequence of characters from a string in TCL.
Say, I have "blahABC:blahDEF:yadamsg=abcd".
I want to extract the substring starting with "msg=" until I reach the end of the string.
Or rather I am interested in extracting "abcd" from the above example string.
Any help is greatly appreciated.
Thanks.

回答1:

Another approach: split the query parameter using & as the separator, find the element starting with "msg=" and then get the text after the =

% set string blahblah&msg=abcd&yada
blahblah&msg=abcd&yada
% lsearch -inline [split $string &] {msg=*}
msg=abcd
% string range [lsearch -inline [split $string &] {msg=*}] 4 end
abcd


回答2:

Regular expressions are the tools for these kind of tasks. The general syntax in Tcl is:

regexp ?switches? exp string ?matchVar? ?subMatchVar subMatchVar ...?

A simple solution for your task would be:

 set string blahblah&msg=abcd&yada

 # match pattern for a =, 0-n characters which are not an & and one &. The grouping with {} is necessary due to special  charactaer clash between  tcl and re_syntax

 set exp {=([^&]*)&}

 # -> is an idiom. In principle it is the variable containing the whole match, which is thrown away and only the submatch is used
b
 regexp $exp $string -> subMatch

 set $subMatch

A nice tool to experiment and play with regexps ist Visual Regexp (http://laurent.riesterer.free.fr/regexp/). I'd recommend to download it and start playing.

The relevant man pages are re_syntax, regexp and regsub

Joachim



回答3:

Code

proc value_of {key matches} {

        set index [lsearch $matches "yadamsg"]

        if {$index != -1} {
                return [lindex $matches $index+1]
        }
        return ""
}

set x "blahABC:blahDEF:yadamsg=abcd:blahGHI"
set matches [regexp -all -inline {([a-zA-Z]+)=([^:]*)} $x]
puts [value_of "yadamsg" $matches]

Output:

abcd

update upvar not needed. see comments.