Python 字符串从拉丁语更改为ASCII

Python 字符串从拉丁语更改为ASCII,python,encoding,decoding,Python,Encoding,Decoding,我曾尝试将字符串的格式从latin1更改为ascii,除了一些字符(æø)外,大多数字符串都做了很好的更改。Æ和Ø 我已经检查了在使用R包(stringi::stri_trans_general(loc1,“拉丁ascii”)时字符是否正确更改,但是Python的unicodedata包没有很好地工作 有没有办法在Python中正确地转换它们?我想可能需要一个额外的字典 作为参考,我已应用以下函数更改格式: unicodedata.normalize('NFKD','Latin strings…

我曾尝试将字符串的格式从latin1更改为ascii,除了一些字符(æø)外,大多数字符串都做了很好的更改。Æ和Ø

我已经检查了在使用R包(stringi::stri_trans_general(loc1,“拉丁ascii”)时字符是否正确更改,但是Python的unicodedata包没有很好地工作

有没有办法在Python中正确地转换它们?我想可能需要一个额外的字典

作为参考,我已应用以下函数更改格式:
unicodedata.normalize('NFKD','Latin strings…).encode('latin1','ignore').decode('ascii')

了解a)什么是编码和解码;b)文本如何工作;c)unicode规范化做什么很重要

字符串没有您所描述的“格式”,因此谈论从latin1转换为ascii格式没有意义。字符串具有表示形式(打印时的外观;或直接在代码中创建时的代码外观;等等)latin1、ascii等都是编码——也就是说,解释如何将字符串存储为原始字节序列的规则

因此,如果你有一个字符串,它不是“拉丁1格式”,仅仅因为源数据是拉丁1编码的-它不是任何格式,因为这个概念不适用。它只是一个字符串

类似地,我们不能要求转换成“ascii格式”的字符串。我们可以要求对字符串进行ascii编码——这是一个字节序列,以及not文本。(在所有计算机科学中,“not”是最重要的“not”之一,因为很多人、工具和程序都会在这方面对你撒谎。)

当然,这里的问题是ascii不能代表所有可能的文本。理论上有超过一百万个“代码点”可以用作字符串的元素(这包括很多非常奇怪的东西,比如表情符号)。latin-1和ascii编码在字符串中的每个代码点都使用一个字节。显然,这意味着它们不能表示所有内容。latin-1仅表示前256个可能的代码点,ascii仅表示前128个。因此,如果我们有来自latin-1源的数据,我们可以得到一个包含以下字符的字符串:
Æ
,这会导致我们的编码步骤出现问题

.encode
'ignore'
选项使编码器跳过编码无法处理的事情。因此,如果您有字符串
'barentsøya'
,因为
ø
不能用ascii表示,它会被跳过,您会得到字节
b'barentsya'
(使用Python显示字节对象的令人遗憾的误导方式)

当您规范化字符串时,您可以将代码点转换为更易于使用的简单格式,并以相同的方式处理不同的字符书写方式或非常相似的字符书写方式。有几种不同的规范化方案。
NFKD
为重音c选择分解表示法角色-也就是说,它将使用两个符号,一个表示普通字母,另一个表示“组合字母”,而不是使用单个符号来表示带重音的字母“版本的重音符号。这可能看起来很有用-例如,它会将重音符号A转换为普通的A和重音符号。您可能认为您可以将其编码为ascii,忽略重音符号,然后获得所需的结果。但是,由于规范化的工作方式,这是不够的


不幸的是,我认为最好的方法是使用第三方库(请注意,建议与堆栈溢出无关),或者自己构建查找表,只翻译每个字符。(请查看内置的字符串方法
translate
maketrans
,以获取相关帮助。)

“没有很好地工作”不是一个很好的问题描述。显示一些代码,显示一些结果,显示一些预期的结果。barentsøya应该更改为barentsoya(并且R包做得很好),但Python将其更改为barentsya(因为encode函数中的“ignore”选项)我必须道歉,我认为unicodedata是实现这一点的方法,但我把它与Python中不包含的内容混淆了。请查看。