类似于 %2 的 Unicode 是什么?

0 投票
2 回答
3033 浏览
提问于 2025-04-18 12:46

我在看别人的内容,遇到了关于unicode的部分,这对我来说总是个难题。如果你能给我一些提示,那就太好了。

情况是这样的:

我有一个名为stopword.txt的停用词文件,内容如下:
         1   781037 
         2   650706 damen
         3   196100 löwe
         4   146044 lego
         5   138280 monster
         6   136410 high
         7   100657 kost%c3%bcm   #this % seems to be strange already
         8    94084 schuhe
         9    93680 kinder
         10   87308 mit

而我尝试读取这个文件的代码是:

     with open('%s/%s'%('path_to_stopwords.txt'), 'r') as f:
          stoplines = [line.decode('utf-8').strip() for line in f.readlines()]

这个decode('utf-8')对我来说似乎很神秘。我的理解是,如果不特别指定,"open"方法读取文件时会把内容当作字符串处理,而这个字符串会自动编码为ascii(这样的话,如果打开的文件里有字符的编码值超过128,比如löwe,使用ascii编码读取时就会丢失信息,因为ö会被截断)。那么,读取到程序后再尝试将其解码为utf-8是什么意思呢?

为了验证我的想法,我尝试用代码检查每一行的内容。

    for line in stoplines:
        print line

这给我的结果是:

    %09
    %21%21%21
    %26
    %26amp%3b
    %28buch%29
    %28gr.
    %2b
    %2bbarbie

我对这些%符号的来源感到很困惑。我是否正确读取了文件的内容?

非常感谢你!

2 个回答

1

几点说明:

  1. 如果文件是UTF-8格式的,你应该一次性把它全部当作UTF-8来打开,而不是一行一行地打开。你可以选择先把文件内容全部读出来,然后再解码(比如用 f.read().decode("utf-8")),或者用 codecs.open 直接以UTF-8格式打开。
  2. 你不需要用 f.readlines(),可以直接用 "for line in f" 来遍历文件。这种方法更省内存,而且代码更简洁。
  3. '%s/%s'%('path_to_stopwords.txt') 这个写法根本就不对。确保你是正确使用的。你可能需要用 os.path.join 来连接路径。
  4. %编码是网址编码。正如上面提到的,你可以使用 urllib.unquote 来处理。
2

在Python 2中,当你打开一个文件并读取内容时,你得到的是一个str类型的字符串,而不是unicode字符串(在Python 3中,你得到的str实际上就是unicode字符串)。

str.decode('utf-8')可以把这个str转换成unicode字符串(前提是这个字符串的编码是UTF8!)。

看起来你的停用词是经过URL编码的:

print urllib.unquote('%c3%bc')
ü

如果这个文件应该是UTF8编码(UTF8本身支持像ü这样的字符),那么使用URL编码确实是多余的,但我觉得这个文件实际上是ASCII编码,而不是UTF8。

所有ASCII字符在UTF8中都对应同样的字符,所以即使不对,依然可以正常工作。

撰写回答