提取查询字符串值

时间:2019-05-22 10:33:48

标签: tcl

如何从以下查询字符串(HTTP url编码)中提取用户名值:Tcl中的username=james&password=pwd

我可以通过Java的request.getParameter("username");获得它,但是如何使用Tcl?

3 个答案:

答案 0 :(得分:0)

第一步是将查询字符串拆分成一个字典(严格来说是不正确的,但是我猜您并不关心有人在查询中放置多个用户名字段的情况串!)。但是,您还需要解码内容的编码,这很糟糕:

proc QueryStringToDict {qs} {
    set mapping {}
    foreach item [split $qs "&"] {
        if {[regexp {^([^=]+)=(.*)$} $item -> key value]} {
            dict set mapping [DecodeURL $key] [DecodeURL $value]
        }
    }
    return $mapping
}
proc DecodeURL {string} {
    # This *is* tricky! The URL encoding of fields is way nastier than you thought!
    set mapped [string map {+ { } \[ "\\\[" \] "\\\]" $ "\\$" \\ "\\\\"} $string]
    encoding convertfrom utf-8 \
            [subst [regsub -all {%([[:xdigit:]]{2})} $string {[format %c 0x\1]}]]
}

set qs "username=james&password=pwd"
set info [QueryStringToDict $qs]
puts "user name is [dict get $info username]"

在8.7(当前为alpha)中,进行内部编码会更加简单;例如,那里不需要subst调用。但是您还没有那个版本的Tcl。没有人拥有(除了坚持要站在最前沿并使自己陷入困境的人之外)。

答案 1 :(得分:0)

假设这是一个CGI环境,该环境将包含

REQUEST_METHOD=GET
QUERY_STRING='username=james&password=pwd'

REQUEST_METHOD=POST
CONTENT_LENGTH=27
# and stdin contains "username=james&password=pwd"

然后使用tcllib's ncgi module

$ cat > cgi.tcl
#!/usr/bin/env tclsh
package require ncgi
::ncgi::parse
array set params [::ncgi::nvlist]
parray params

$ printf "username=james&password=pwd" | env REQUEST_METHOD=POST CONTENT_LENGTH=27 ./cgi.tcl
params(password) = pwd
params(username) = james

$ env REQUEST_METHOD=GET QUERY_STRING='username=james&password=pwd' ./cgi.tcl
params(password) = pwd
params(username) = james

答案 2 :(得分:0)

多纳尔的建议的替代方案,共享精神,但要依靠电池:tcllib rest package

(1)处理查询(作为有效URL的一部分)

# Allow overriding xeno-config on make command line
XENO_CONFIG=xeno-config

prefix := $(shell $(XENO_CONFIG) --prefix)

ifeq ($(prefix),)
$(error Please add <xenomai-install-path>/bin to your PATH variable)
endif

CC := $(shell $(XENO_CONFIG) --skin=posix --cc)
STD_CFLAGS  := $(shell $(XENO_CONFIG) --skin=posix --cflags) -g
STD_LDFLAGS := $(shell $(XENO_CONFIG) --skin=posix --ldflags) -g -lrtdm

STD_TARGETS := rtt_rt

all: $(STD_TARGETS)

$(STD_TARGETS): $(STD_TARGETS:%=%.c)
    $(CC) -o $@ $< $(STD_CFLAGS) $(STD_LDFLAGS)

clean:
    $(RM) -f *.o *~ $(STD_TARGETS) 

(2)运行URL解码器(例如Donal的一个或Rosetta code的一个):

% package req rest
1.3.1
% set query [rest::parameters ?username=jo%3Dhn]; # http:// is default scheme, ? is minimum URL boilerplate
username jo%3Dhn

然后:

% proc urlDecode {str} {
   set specialMap {"[" "%5B" "]" "%5D"}
   set seqRE {%([0-9a-fA-F]{2})}
   set replacement {[format "%c" [scan "\1" "%2x"]]}
   set modStr [regsub -all $seqRE [string map $specialMap $str] $replacement]
   return [encoding convertfrom utf-8 [subst -nobackslash -novariable $modStr]]
}