Python返回单个非ASCII字符字符串的长度为2

4

我试图获取字符串中选定单词的范围。当处理 İ 字符时,我注意到Python 的下列行为:

len("İ")
Out[39]: 1

len("İ".lower())
Out[40]: 2

# when `upper()` is applied, the length stays the same
len("İ".lower().upper())
Out[41]: 2

为什么大小写相同的字符的长度不同(这似乎非常令人困惑/不期望)?
有人知道是否还有其他字符也会出现这种情况吗? 谢谢!
编辑:
另一方面,例如Î,长度保持不变:
len('Î')
Out[42]: 1

len('Î'.lower())
Out[43]: 1

有没有人知道还有哪些字符会发生这种情况?据我所知,目前只有那个İ会出现这种情况。对于一个小写字符,在使用str.upper后变长的有数百个,其中最著名的是ß。 - wim
感谢您的评论,我之前也不知道这种行为。 - lux7
2个回答

3
这是因为小写的 'İ' 实际上是两个字符组成的 'i̇'
>>> import unicodedata
>>> unicodedata.name('İ')
'LATIN CAPITAL LETTER I WITH DOT ABOVE'
>>> unicodedata.name('İ'.lower()[0])
'LATIN SMALL LETTER I'
>>> unicodedata.name('İ'.lower()[1])
'COMBINING DOT ABOVE'

一个字符是一个组合点,你的浏览器可能会将其与最后一个引号重叠渲染,因此您可能无法看到它。但如果你将其复制粘贴到你的Python控制台中,你应该能够看到它。


如果你尝试:

print('i̇'.upper())

你应该获得

İ

非常感谢您的回答!unicodedata.name('İ') 方法确实非常有趣。我仍然不理解的问题是,为什么会发生这种情况?这不是一种不希望出现的行为吗? - lux7

-1

我认为问题在于ASCII中未定义该符号的小写字符。

.lower()函数可能会对与字符相关联的ASCII数字执行固定偏移量,因为这适用于英文字母表。


这是Unicode - 与ASCII编码无关。而且这不是 str.lower 实际所做的事情。 - wim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接