如何规范Python字符串编码

2024-05-16 21:23:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个带字符串的文本文件。这些字符串最终表示URL路径(不是完整的URL),但已经用多种方式编码。以下是文件摘录:

25_%D1%80%D0%B0%D1%88%D3%99%D0%B0%D1%80%D0%B0
2_\xD1\x80\xD0\xB0\xD1\x88\xD3\x99\xD0\xB0\xD1\x80\xD0\xB0
5_%D1%80%D0%B0%D1%88%D3%99%D0%B0%D1%80%D0%B0
\xD0\x90\xD0\xBA\xD0\xB0\xD0\xB1\xD0\xB0
\xD0\x90\xD1\x88\xD3\x99\xD0\xB0\xD1\x85\xD1\x8C\xD0\xB0
function.fopen
Бразилиа
Валерии_Маиромиан
Rome,_Italy
Rome%2C_Italy

我想保证所有这些字符串都有一个通用格式,因为在加载文件之后,我需要进行字符串比较(例如,Rome%2C_Italy应该等于Rome,_Italy)。在

有些行是URL编码的,可以很容易地unquoted

^{pr2}$

前一个代码的输出是:

25_рашәара
2_\xD1\x80\xD0\xB0\xD1\x88\xD3\x99\xD0\xB0\xD1\x80\xD0\xB0
5_рашәара
\xD0\x90\xD0\xBA\xD0\xB0\xD0\xB1\xD0\xB0
\xD0\x90\xD1\x88\xD3\x99\xD0\xB0\xD1\x85\xD1\x8C\xD0\xB0
function.fopen
Бразилиа
Валерии_Маиромиан
Rome,_Italy
Rome,_Italy

我最好的尝试是使用以下代码:

import urllib
with open("input.txt") as f:
    for line in f:
        str = urllib.unquote(line.rstrip()).encode("utf8")
        print str

输出如下:

25_рашәара
2_\xD1\x80\xD0\xB0\xD1\x88\xD3\x99\xD0\xB0\xD1\x80\xD0\xB0
5_рашәара
\xD0\x90\xD0\xBA\xD0\xB0\xD0\xB1\xD0\xB0
\xD0\x90\xD1\x88\xD3\x99\xD0\xB0\xD1\x85\xD1\x8C\xD0\xB0
function.fopen
Бразилиа
Валерии_Маиромиан
Rome,_Italy
Rome,_Italy

好像忽略了一些台词!在

在任何情况下,我认为最好是简单地对所有这些字符串进行URL编码(与1行一样),但是urllib.quote()方法在已经是URL编码的行上不能很好地工作(它将再次对%进行编码!)。在

如果你能帮我澄清我的困惑,我将不胜感激!在


Tags: 字符串url编码romeitalyx80xb1xb0
2条回答

这段代码使用了与Eugene Lisitsky相似的方法,只是它运行在python2上。在python2中,可能有一种更简洁的方法来实现这一点,但它似乎可以正确地处理操作中的数据

顺便说一句,当你问到一个与Unicode有关的问题时,你应该用一个适当的Python版本标记来标记你的问题,因为python3中的Unicode处理方式与python2中的工作方式(或者失败了:)大不相同。在

import codecs
import urllib

fname = 'input.txt'

with open(fname, 'rb') as f:
    for line in f:
        line = line.strip()
        line = urllib.unquote(line)
        if r'\x' in line:
            line = codecs.unicode_escape_decode(line)[0]
            line = line.encode('latin1')

        line = line.decode('utf-8')
        print repr(line), line

输出

^{pr2}$

如您所见,我已经将所有字符串转换为Unicode对象。如果出于某种原因,您希望它们成为纯python2字符串,只需消除line = line.decode('utf-8')行。在

你可以用codecs.unicode_escape_解码要解码反斜杠转义字符,请执行以下操作:

>>> import codecs
>>> s=r"\xD0\x90\xD0\xBA\xD0\xB0\xD0\xB1\xD0\xB0"
>>> print(s)
\xD0\x90\xD0\xBA\xD0\xB0\xD0\xB1\xD0\xB0
>>> s1=codecs.unicode_escape_decode(s)[0]
>>> print(s1)
Ðкаба
>>> bytes(s1,'latin1').decode('utf-8')
'Акаба'
>>>

相关问题 更多 >