繁体   English   中英

将 unicode 字符转换为基本字符

[英]Convert unicode character to base character

我有一个字节数组.. b'containing ab\xd1\x96cycle'

我正在尝试将此字符串转换为等效的 ascii: containing a bicycle

我怎样才能做到这一点?

请注意,这只是一个示例,还有其他示例,例如:

containing a \xd1\x95eaplane -> containing a seaplane

containing an \xd0\xb0irplane -> containing an airplane

我不想通过字典查找进行 static 替换。

有没有办法即时执行此操作?

我试过这个但它完全删除了角色:

question.encode('ascii', 'ignore') -> bcontaining a bcycle'

请注意,我正在尝试查找 ACTUAL 字符,而不是 unicode 中表示的“相似”字符。

谢谢

你似乎走错了方向。 如果你有字节并且你想要一个字符串,那就是解码操作,而不是编码 这工作得很好,我想给你你想要的:

print(b'containing a b\xd1\x96cycle'.decode("utf-8"))

结果:

containing a bіcycle

明确一点,当你说:

我有一个看起来像这样的字符串 b'containing ab\xd1\x96cycle'

你实际上没有字符串,你有一个字节object...一个字节数组。

更新:我从不喜欢半途而废的问题,即使它涉及的内容与要求的内容有点不同......

Unicode 没有向下映射到 ASCII 字符的概念......将 Unicode“相似”转换为它们的 ASCII 等价物。 但是,有些软件包试图这样做。 然而,他们必须在幕后进行某种带外映射。 一个这样的 package 是Unidecode 这是使用 package 得出我认为是您想要的结果的样子:

import unidecode
unicodeBytes = b'containing a b\xd1\x96cycle'
unicodeStr = unicodeBytes.decode("utf-8")
mappedUnicodeStr = unidecode.unidecode(unicodeStr)
asciiBytes = mappedUnicodeStr.encode("ascii")
print(asciiBytes)

结果:

b'containing a bicycle'

结果字节 object 的字符都是纯 ASCII。 请查看unidecode package 的文档,并注意其中讨论的注意事项。

您正在查看包含以 UTF-8 编码的 ascii 相似字符的字符串的字节表示。例如, \xd1\x96ѕ ,“西里尔小写字母 dze”。 要查看它,请解码指定“utf-8”编码的字符串。 (可选,如果这是您的系统默认设置。)

>>> original = b"\xd1\x95eaplane"
>>> nice = original.decode("utf-8")
>>> print(nice)
ѕeaplane

请注意,这看起来像s ,但它不是s

在 python 中,字符串在内部表示为 unicode,从中可以将字符串编码为所需的编码(在本例中为ascii )。

https://docs.python.org/3/howto/unicode.html#:~:text=Python's%20string%20type%20uses%20the,all%20these%20different%20possible%20characters

Python 的字符串类型使用 Unicode 标准来表示字符,这让 Python 程序可以处理所有这些不同的可能字符。

unicode_representation = b'containing a b\xd1\x96cycle'.decode("utf8")
ascii_encoded = unicode_representation.encode("ascii", "ignore")

但是,如前所述,在这种情况下,“i”将从 output 中的“bicycle”中删除,因为它无法编码为 ascii。

通过在字符上调用ord() ,您可以看到字符是不同的 unicode 代码点。

s = b'containing a b\xd1\x96cycle'
u = s.decode("utf8")
for c in u:
    print(c, ord(c))

会给你:

c 99
o 111
n 110
t 116
a 97
i 105
n 110
i 105
n 110
g 103
  32
a 97
  32
b 98
і 1110
c 99
y 121
c 99
l 108
e 101

如您所见105 != 1110 ,其中105可以编码为 ascii,而1110不能,即使它们在视觉上看起来相同。

如果你想获得最接近 unicode 的 ascii 表示,你需要在某处定义一个映射来执行转换。

是这样的:

similar_ascii = {
    1110: "i",
}
def convert_to_ascii_codepoints(s):
    result = []
    for c in s:
        converted_char = similar_ascii.get(ord(c), None)
        if converted_char:
            c = converted_char
        result.append(c)
    return "".join(result)

s = b'containing a b\xd1\x96cycle'
u = s.decode("utf8")
result = convert_to_ascii_codepoints(u)
result.encode("ascii")

看起来这个 package 可能已经为您定义了必要的映射和转换函数。

https://github.com/ajanin/uni2ascii

** 未经测试 **

from uni2ascii import uni2ascii

s = b'containing a b\xd1\x96cycle'
ascii_string = uni2ascii(s)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM