【问题标题】:String change from Latin to ASCII字符串从拉丁文更改为 ASCII
【发布时间】:2021-06-21 20:04:42
【问题描述】:

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

我检查了使用 R 包时字符是否正确更改 (stringi::stri_trans_general(loc1, "latin-ascii) 但 Python 的 unicodedata 包不能正常工作。

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

有关信息,我已应用以下功能来更改格式: unicodedata.normalize('NFKD', "拉丁字符串...").encode('latin1', 'ignore').decode('ascii')

【问题讨论】:

  • “没有很好地工作”不是一个好的问题描述。显示一些代码,显示一些结果,显示一些预期结果。
  • barentsøya 应该改为 barentsoya(R 包做得很好)但 Python 将其改为 barentsya(因为编码函数中的 'ignore' 选项)
  • 我必须道歉,我认为 unicodedata 是这样做的方法,但我把它与 Python 不包含的unidecode 混淆了。看看吧。
  • 你可能想看看模块unidecode,它做了我认为你想要的,认为这很难说,因为你实际上并没有说你想要像@这样的字符发生什么987654324@ 和øß,只是设置errors="ignore" 的结果不是你所期望的,这就是R 所做的(期望我们都知道R 所做的事情是不明智的)。 unidecode 所做的是 aeoss。那可能也不是你想要的。

标签: python encoding decoding


【解决方案1】:

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

在您描述的意义上,字符串没有“格式”,因此谈论从 latin1 转换为 ascii 格式没有意义。该字符串具有表示(打印出来时的样子;或者直接在代码中创建代码时的样子;等等),并且可以编码。 latin1、ascii 等是 encodings - 这意味着解释如何将字符串存储为原始字节序列的规则。

因此,如果您有一个字符串,它不是“latin1 格式”,因为 source 数据是 latin1 encoding - 它不是 any 格式,因为该概念不适用。 只是一个字符串

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

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

.encode'ignore' 选项使编码器跳过编码无法处理的内容。所以如果你有字符串'barentsøya',因为ø不能用ascii表示,它会被跳过,你会得到bytesb'barentsya'(不幸的是,使用Python显示字节对象的误导方式回给你)。

当您规范化一个字符串时,您将代码点转换为一些更易于使用的普通格式,并处理不同的字符书写方式 - 或不同的书写非常相似字符的方式 -同样的方法。有几种不同的归一化方案。 NFKD 选择 decomposed 表示重音字符 - 也就是说,它不会使用单个符号来表示带有重音的字母,而是使用两个符号,一个表示普通字母,一个代表重音的“组合”版本。这似乎很有用——例如,它会将带重音的 A 变成普通的 A 和重音字符。您可能认为您可以将其编码为 ascii,让重音字符被忽略,并获得您想要的结果。然而,事实证明这还不够,因为规范化是如何工作的。

不幸的是,我认为您能做的最好的事情就是使用第三方库(请注意,建议与 Stack Overflow 无关)或自己构建查找表并仅翻译每个字符。 (查看内置字符串方法 translatemaketrans 以获得帮助。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    相关资源
    最近更新 更多