在Python3中更正一串非英文字符的长度

时间:2017-12-18 01:32:23

标签: python python-3.x python-unicode

我在文件中给了一串希伯来字符(以及其他一些阿拉伯字符。我也不知道它们)

צוֹר

当我从Python3中的文件加载此字符串时

fin = open("filename")
x = next(fin).strip()

x的长度似乎为5

>>> len(x)
5

它的unicode utf-8编码是

>>> x.encode("utf-8")
b'\xd7\xa6\xd7\x95\xd6\xb9\xd7\xa8\xe2\x80\x8e'

但是,在浏览器中,很明显这些希伯来字符的长度为3。

如何正确地获得长度?为什么会发生这种情况?

我知道Python 3默认是unicode,所以我没想到会出现这样的问题。

4 个答案:

答案 0 :(得分:5)

原因是包含的文本包含控制字符\u200e,它是一个用作Left-to-right标记的不可见字符(当您将多种语言混合在一起以区分从左到右时通常使用和从右到左)。此外,它还包括元音“字符”(第二个字符上方的小点,表示如何发音)。

例如,如果用空字符串替换LTR标记,则长度为4:

>> x = 'צוֹר'
>> x
'צוֹר\u200e' # note the control character escape sequence
>> print(len(x))
5

>> print(len(x.replace('\u200e', ''))
4

如果您只想要严格的字母字符和空格字符的长度,您可以执行re.sub所有非空格非单词字符的操作:

>> print(len(re.sub('[^\w\s]', '', x)))
3

答案 1 :(得分:4)

Unicode字符具有不同的类别。在你的情况下:

>>> import unicodedata
>>> s = b'\xd7\xa6\xd7\x95\xd6\xb9\xd7\xa8\xe2\x80\x8e'.decode("utf-8")
>>> list(unicodedata.category(c) for c in s)
['Lo', 'Lo', 'Mn', 'Lo', 'Cf']
  • Lo:信,其他(不是大写,小写等)。这些是“真正的”字符
  • Mn:马克,非空间。这是某种类型的重音字符与前一个字符相结合
  • Cf:控制,格式化。这里它切换回从左到右的写入方向

答案 2 :(得分:0)

你试过io libary吗?

>>> import io
>>> with io.open('text.txt',  mode="r", encoding="utf-8") as f:
     x = f.read()
>>> print(len(x))

您还可以尝试codecs

>>> import codecs
>>> with codecs.open('text.txt', 'r', 'utf-8') as f:
     x = f.read()
>>> print(len(x))

答案 3 :(得分:0)

使用utf-8编码打开文件。

fin = open('filename','r',encoding='utf-8')

with open('filename','r',encoding='utf-8') as fin:
    for line1 in fin:
        print(len(line1.strip()))