【问题标题】:Why does this Python 3 code fail to remove Unicode accented characters using str.translate()?为什么此 Python 3 代码无法使用 str.translate() 删除 Unicode 重音字符?
【发布时间】:2014-07-28 14:48:24
【问题描述】:

我正在尝试像这样在 Python 3 中规范化字符串中的重音字符:

from bs4 import BeautifulSoup
import os

def process_markup():
    #the file is utf-8 encoded
    fn = os.path.join(os.path.dirname(__file__), 'src.txt') #
    markup = BeautifulSoup(open(fn), from_encoding="utf-8")

    for player in markup.find_all("div", class_="glossary-player"):
        text = player.span.string
        print(format_filename(text)) # Python console shows mangled characters not in utf-8
        player.span.string.replace_with(format_filename(text))

    dest = open("dest.txt", "w", encoding="utf-8")
    dest.write(str(markup))

def format_filename(s):
    # prepare string
    s = s.strip().lower().replace(" ", "-").strip("'")

    # transliterate accented characters to non-accented versions
    chars_in = "àèìòùáéíóú"
    chars_out = "aeiouaeiou"
    no_accented_chars = str.maketrans(chars_in, chars_out)
    return s.translate(no_accented_chars)

process_markup()

输入的 src.txt 文件是 utf-8 编码的:

<div class="glossary-player">
    <span class="gd"> Fàilte </span><span class="en"> Welcome </span>
</div>
<div class="glossary-player">
    <span class="gd"> àèìòùáéíóú </span><span class="en"> aeiouaeiou </span>
</div>

输出文件 dest.txt 如下所示:

<div class="glossary-player">
<span class="gd">fã ilte</span><span class="en"> Welcome </span>
</div>
<div class="glossary-player">
<span class="gd">ã ã¨ã¬ã²ã¹ã¡ã©ã­ã³ãº</span><span class="en"> aeiouaeiou </span>
</div>

我试图让它看起来像这样:

<div class="glossary-player">
<span class="gd">failte</span><span class="en"> Welcome </span>
</div>
<div class="glossary-player">
<span class="gd">aeiouaeiou</span><span class="en"> aeiouaeiou </span>
</div>

我知道有像 unidecode 这样的解决方案,但只是想找出我在这里做错了什么。

【问题讨论】:

  • 没有“ANSI 编码”。你的意思是你得到了 Windows 所谓的 ANSI,即Windows-1252 之类的东西?或者你真的恢复了 Unicode?​​span>
  • 感谢您的更正 - 令人误解的是,Notepad++ 有一个“在 ANSI 中编码”菜单选项,我指的是。我没有找回 Unicode。
  • 真的吗?那么src.txt 和你的 Python 程序的编码是什么?如果您处理的重音字符不是 UTF-8,我预计会出现错误。
  • dest.txt 看起来像是有效的 UTF-8,您正在使用损坏或配置错误的东西查看它。
  • 您如何查看生成的文件?

标签: python unicode beautifulsoup


【解决方案1】:

问题在于,as triplee suggested,文件被解释为错误的编码。

文件中的数据是正确的(如十六进制转储所示),但可能是由于缺少字符集声明,Python 没有将其读取为 utf-8,而是 cp1252。

为了解决这个问题,有必要在使用 Python 的 open() 方法打开文件时显式声明编码,因此行:

markup = BeautifulSoup(open(fn), from_encoding="utf-8")

需要改成:

markup = BeautifulSoup(open(fn, encoding="utf-8"))

【讨论】:

  • 还需要# -*- coding: utf-8 -*-作为脚本文件的第一行来解决小问题
【解决方案2】:

我强烈怀疑您的 HTML 文件包含类似

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">

这基本上迫使 BeautifulSoup 将 UTF-8 重新解释为 ISO-8859-1(或您拥有的任何旧字符集;Windows-1252?不寒而栗)。

您可以在许多其他地方将charset= 属性添加到 HTML 块中,但这是典型的罪魁祸首。

【讨论】:

  • 这部分基于chat 来自我之前尝试的答案。
  • 猜得好,但该文件是一个 HTML 片段 - 它没有设计为 HTML 。
【解决方案3】:

chars.translate(no_accented_chars) 不会修改 chars。它返回一个应用了翻译的新字符串。如果你想使用翻译后的字符串,把它保存到一个变量中(可能是原来的chars变量):

chars = chars.translate(no_accented_chars)

或者直接传递给write调用:

dest.write(chars.translate(no_accented_chars))

【讨论】:

  • 呵呵,我错过了作业丢失了。
  • 完美答案! :) 好的,在粘贴部分代码时这是一个错字。我会用完整的代码编辑问题,所以现在只是一个upvote,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2017-06-17
  • 2017-10-16
  • 2010-11-22
  • 2018-05-08
相关资源
最近更新 更多