如何从以下查询字符串(HTTP url编码)中提取用户名值:Tcl中的username=james&password=pwd
?
我可以通过Java的request.getParameter("username");
获得它,但是如何使用Tcl?
答案 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"
$ 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]]
}