首页 > 解决方案 > 如何在带有重音字符的 .txt 文件上使用 .replace() ?

问题描述

所以我有一个代码,它接受一个 .txt 文件并将其作为字符串添加到变量中。

然后,我尝试在其上使用 .replace() 将字符“ó”更改为“o”,但它不起作用!控制台打印同样的东西。

代码:

def normalize(filename):

    #Ignores errors because I get the .txt from my WhatsApp conversations and emojis raise an error.
    #File says: "Es una rubrica de evaluación." (among many emojis)

    txt_raw = open(filename, "r", errors="ignore")
    txt_read = txt_raw.read()


    #Here, only the "o" is replaced. In the real code, I use a for loop to iterate through all chrs.

    rem_accent_txt = txt_read.replace("ó", "o")
    print(rem_accent_txt)

    return

预期输出:

"Es una rubrica de evaluacion."

电流输出:

"Es una rubrica de evaluación."

它不会打印错误或任何内容,它只是按原样打印。

我相信问题在于字符串来自文件这一事实,因为当我只是创建一个字符串并使用代码时,它确实有效,但是当我从文件中获取字符串时它不起作用。

编辑:解决方案!

感谢@juanpa.arrivillaga 和@das-g,我想出了这个解决方案:

from unidecode import unidecode

def get_txt(filename):

    txt_raw = open(filename, "r", encoding="utf8")
    txt_read = txt_raw.read()

    txt_decode = unidecode(txt_read)

    print(txt_decode)

    return txt_decode

标签: pythonstringreplace

解决方案


几乎可以肯定,正在发生的事情是你有一个非规范化的 unicode 字符串。本质上,有两种方法可以"ó"在 unicode 中创建:

>>> combining = 'ó'
>>> composed = 'ó'
>>> len(combining), len(composed)
(2, 1)
>>> list(combining)
['o', '́']
>>> list(composed)
['ó']
>>> import unicodedata
>>> list(map(unicodedata.name, combining))
['LATIN SMALL LETTER O', 'COMBINING ACUTE ACCENT']
>>> list(map(unicodedata.name, composed))
['LATIN SMALL LETTER O WITH ACUTE']

只需标准化您的字符串:

>>> composed == combining
False
>>> composed == unicodedata.normalize("NFC", combining)
True

虽然,退后一步,你真的想删除重音吗?或者你只是想标准化为组合,就像上面一样?

顺便说一句,您在阅读文本文件时不应忽略错误。您应该使用正确的编码。我怀疑正在发生的事情是您正在使用不正确的编码编写文本文件,因为您应该能够很好地处理表情符号,它们在 unicode 中并没有什么特别之处。

>>> emoji = ""
>>> print(emoji)

>>>
>>> unicodedata.name(emoji)
'GRINNING FACE'

推荐阅读