有没有一种函数可以解码编码的Unicode UTF-8字符串,例如来自表格?

5
我希望能够使用html表单和Rebol cgi存储一些数据。我的表单如下所示:
<form action="test.cgi" method="post" >

     Input:

     <input type="text" name="field"/>
     <input type="submit" value="Submit" />

</form>

然而对于像中文这样的Unicode字符,我会得到带有百分号的编码形式的数据,例如%E4%BA%BA

(这是汉字“人”的例子……它作为Rebol二进制文字的UTF-8形式为#{E4BABA}

系统中是否有一个函数或现有库可以直接解码这个? dehex目前似乎没有覆盖此情况。 我目前正在手动解码,方法是删除百分号并构造相应的二进制数据,就像这样:

data: to-string read system/ports/input
print data

;-- this prints "field=%E4%BA%BA"

k-v: parse data "="
print k-v

;-- this prints ["field" "%E4%BA%BA"]

v: append insert replace/all k-v/2 "%" "" "#{" "}"
print v

;-- This prints "#{E4BABA}" ... a string!, not binary!
;-- LOAD will help construct the corresponding binary
;-- then TO-STRING will decode that binary from UTF-8 to character codepoints

write %test.txt to-string load v
2个回答

3

我有一个叫做 AltWebForm 的库,可以对百分号编码的网络表单数据进行编码和解码:

do http://reb4.me/r3/altwebform
load-webform "field=%E4%BA%BA"

这里描述了该库:Rebol and Web Forms


2
似乎与票号1986有关,讨论了这是一个“错误”还是因为互联网在规范下发生了变化:

Have DEHEX convert UTF-8 sequences from browsers as Unicode

如果您有关于中文已成为标准的具体经验,并想要发表意见,那将是非常有价值的。
另外,上面的特定情况可以在PARSE中选择以下方式处理:
key-value: {field=%E4%BA%BA}

utf8-bytes: copy #{}

either parse key-value [
    copy field-name to {=}
    skip
    some [
        and {%}
        copy enhexed-byte 3 skip (
            append utf8-bytes dehex enhexed-byte
        )
    ]
] [
    print [field-name {is} to string! utf8-bytes]
] [
    print {Malformed input.}
]

那将输出:
field is 人

带有一些评论的文字:
key-value: {field=%E4%BA%BA}

;-- Generate empty binary value by copying an empty binary literal     
utf8-bytes: copy #{}

either parse key-value [

    ;-- grab field-name as the chars right up to the equals sign
    copy field-name to {=}

    ;-- skip the equal sign as we went up to it, without moving "past" it
    skip

    ;-- apply the enclosed rule SOME (non-zero) number of times
    some [
        ;-- match a percent sign as the immediate next symbol, without
        ;-- advancing the parse position
        and {%}

        ;-- grab the next three chars, starting with %, into enhexed-byte
        copy enhexed-byte 3 skip (

            ;-- If we get to this point in the match rule, this parenthesized
            ;-- expression lets us evaluate non-dialected Rebol code to 
            ;-- append the dehexed byte to our utf8 binary
            append utf8-bytes dehex enhexed-byte
        )
    ]
] [
    print [field-name {is} to string! utf8-bytes]
] [
    print {Malformed input.}
]

(请注意,“simple parse”被弃用,而采用SPLIT的增强版。因此,编写类似parse data "="的代码现在可以改为split data "=",或者如果您查看它们的话,还有其他很酷的变体...样例在票证中。)

这个方法更加清晰。使用load v构建二进制文件不是很自然。http://curecode.org/中的两个链接非常棒。我会仔细阅读它们的。你的代码有一个小错误,还是我的版本不支持?在我的控制台中,代码`{%} -1 skip无法工作(脚本错误:值超出范围:-1)。我将其改为to {%}`,然后它就可以工作了。最后,非常感谢您的格式化和重新组织。 - Wayne Cui
@WayneTsui 没问题,抱歉出现错误...我可能是从一个我认为可以工作但实际上不行的版本中复制过来的。使用 TO 的问题在于它会将解析位置提前到该规则之前...因此,像 field=x123\abc%E4BA%BA 这样格式不正确的输入也会被接受。我会研究如何正确地向后跳过,但 AND 将确保只有在百分号是紧接着的下一个位置而没有提前时才触发规则... - HostileFork says dont trust SE

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接