2014-09-19 30 views
0

使用下面的代码(PHP)我发送一个字符串到Python程序:如何解码unicode python参数?

shell_exec("python3 /var/www/html/app.py \"$text\""); 

$text变量包含非英文字符串。问题是,当我打印在Python的论点print(sys.argv)我得到这样一个结果:

['/var/www/html/app.py', '\udcd8\udca8\udcd8\udcaa\udcd8\udcb5\udcd8\udcb4\udcda\udca9 \udcd8\udcae\udcd8\udcab\udcd9\udc87\udcd8\udca8 \udcd8\udcaa\udcd8\udcb4\udcd8\udcb5\udcd8\udcab'] 

我怎么这个unicode字符串转换为蟒文字的原始形式?

+0

你期望的输出?这些码点是代理。 – geoffspear 2014-09-19 17:20:03

+0

@Wooble我想在一个使用普通字符串而不是unicodes的函数中使用这个文本。 – hpn 2014-09-19 18:01:42

回答

2

Python使用您的LOC ale的编码来解码从命令行获取的字节。默认的C语言环境使用ascii。它似乎在utf-8中似乎是$text。因此,Python必须使用surrogateescape错误处理程序将这些字节解码为文字sys.argv[1],这会产生您在输出中看到的单独替代项,例如'\udcd8'

你可以使用UTF-8码例如,LC_ALL=C.UTF-8或手动重新编码的参数:sys.argv[1].encode(locale.getpreferredencoding(True), 'surrogateescape').decode('utf-8')

>>> s = u'\udcd8\udca8\udcd8\udcaa\udcd8\udcb5\udcd8\udcb4\udcda\udca9 \udcd8\udcae\udcd8\udcab\udcd9\udc87\udcd8\udca8 \udcd8\udcaa\udcd8\udcb4\udcd8\udcb5\udcd8\udcab' 
>>> print(s.encode('ascii', 'surrogateescape').decode('utf-8')) 
بتصشک خثهب تشصث 
+0

手动重新编码参数时出现此错误:'UnicodeEncodeError:'ascii'编解码器无法编码0-5位置的字符:序号不在范围内(128)' – hpn 2014-09-20 18:45:49

+0

@hpn:我已经添加了代码示例,没有错误 – jfs 2014-09-21 04:28:13

2
shell_exec("python3 /var/www/html/app.py \"$text\""); 

(我希望$text强烈消毒,逃了出来,或静!如果用户输入了在这里你有一个可怕的远程执行代码漏洞!)

'\udcd8\udca8\udcd8\udcaa\udcd8\udcb5\udcd8... 

确定什么曾经发生在这里PHP已经向Python传递了UTF-8编码的字符串,但Python不知道命令行输入是UTF-8。 (通常当你将Python作为命令运行时,它可以从你的终端运行,但是当它运行在web服务器中的Python时,没有终端。)

不知道输入是什么,默认为纯ASCII 。输入中的高字节在ASCII中无效,但Python 3对无效字节有一个“surrogateescape”回退处理程序,将其解码为Unicode字符串时应用于命令行。这会产生无效的UTF-16替代码单元U + DC80-U + DCFF,但至少可以让原始高字节在需要时恢复。

因此,要么:

  • PYTHONIOENCODING环境变量设置为UTF-8执行Python之前,因此它知道正确的编码是摆在首位的,或者

  • 变化的Python脚本预 - 流程的输入与恢复正确的输入sys.argv[1].encode('utf-8', 'surrogateescape').decode('utf-8')

+0

'PYTHONIOENCODING'对'sys.argv'没有影响。您应该使用*相同的*字符编码来编码(不要硬编码“utf-8”),正如Python用来解码'sys.argv'一样。 – jfs 2014-09-20 05:59:25

+0

@bobince +1并感谢您的警告!将PYTHONENCODING设置为utf-8不起作用,但是'LANG = en_US.utf-8'工作 – hpn 2014-09-20 18:50:27