【问题标题】:Why is this Turkish character being corrupted when I lowercase it?为什么这个土耳其字符在我小写时会被破坏?
【发布时间】:2017-03-19 23:35:50
【问题描述】:

我正在尝试将一些包含土耳其语字符的单词转换为小写。

从 utf-8 编码的文件中读取单词:

with open(filepath,'r', encoding='utf8') as f:
            text=f.read().lower()

当我尝试转换为小写时,土耳其语字符 İ 被损坏。但是,当我尝试转换为大写时,它工作正常。

这里是示例代码:

str = 'İşbirliği'
print(str)
print(str.lower())

这是损坏后的样子:

这是怎么回事?

一些可能有用的信息:

  • 我使用的是 Windows 10 cmd 提示符
  • Python 3.6.0 版
  • chcp 设置为 65001

【问题讨论】:

  • 发布实际文字而非图片链接,否则难以复制粘贴自己尝试。
  • @MarkTolonen 在这种情况下,图像是证明问题的唯一合理方式。
  • @zero 啊,好的。最好也从控制台粘贴文本,即使当我们在浏览器中看到它时它可能会发生一点变化。
  • @Zero 可能还需要一张图片,但对于没有土耳其语键盘的人来说,实际的原始文本仍然很有帮助。

标签: python utf-8 character-encoding case-sensitive turkish


【解决方案1】:

它没有损坏。

土耳其语同时有一个带点的小写i 和一个无点的小写ı,类似地还有一个带点的大写İ 和一个不带点的大写I

这在将带点的大写İ转换为小写时提出了一个挑战:如何保留信息,如果需要将其转换回大写,则应将其转换回带点的İ

Unicode 解决这个问题的方法如下:İ 转换为小写时,实际上是转换为标准拉丁文i 加上组合字符U+0307 "COMBINING DOT ABOVE"。您所看到的是您的终端无法正确渲染(或者,更重要的是,避免渲染)组合字符,这与 Python 无关。

您可以使用unicodedata.name() 看到这正在发生:

>>> import unicodedata
>>> [unicodedata.name(c) for c in 'İ']
['LATIN CAPITAL LETTER I WITH DOT ABOVE']
>>> [unicodedata.name(c) for c in 'İ'.lower()]
['LATIN SMALL LETTER I', 'COMBINING DOT ABOVE']

...尽管在正常工作且配置正确的终端中,它会毫无问题地呈现:

>>> 'İ'.lower()
'i̇'

附带说明,如果您将其转换回大写,它将保持分解后的形式:

>>> [unicodedata.name(c) for c in 'İ'.lower().upper()]
['LATIN CAPITAL LETTER I', 'COMBINING DOT ABOVE']

…虽然你可以用unicodedata.normalize()重新组合它:

>>> [unicodedata.name(c) for c in unicodedata.normalize('NFC','İ'.lower().upper())]
['LATIN CAPITAL LETTER I WITH DOT ABOVE']

有关详细信息,请参阅:

【讨论】:

  • 感谢您在帖子中提供清晰的信息。如果它只是渲染我不会介意的。我正在使用将文本拆分为单词的正则表达式。因为该单词中有一个额外的字符会导致错误的拆分。 >>> re.split('\W+','İşbirliği önemlidir') ['İşbirliği', 'önemlidir'] >>> re.split('\W+','İşbirliği önemlidir'.lower()) ['i ', 'şbirliği', 'önemlidir']
  • 我认为这是 Python 的 re.split() 中的一个错误。 \W 中不应包含连接字符,尽管语义有点复杂(如果它连接到非单词字符怎么办?你能做到吗?)
  • 我同意@tripleee 的观点,这是re 中的一个错误。更现代的 regex 将组合字符视为单词字符:regex.split('\W+','İşbirliği önemlidir'.lower()) 按预期返回 ['i̇şbirliği', 'önemlidir'],以防万一。
  • 谢谢@tripleee 我在想编码有问题。正则表达式按预期工作。
猜你喜欢
  • 2014-06-24
  • 2020-10-02
  • 2016-06-06
  • 2012-05-13
  • 1970-01-01
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多