返回 Unicode 字符串的前 N 个字符
我有一个unicode字符串,我需要返回前N个字符。现在我这样做:
result = unistring[:5]
但unicode字符串的长度和字符的长度是不一样的。这种情况下,有什么好的办法吗?难道只能用正则表达式吗?
补充说明:更多信息
unistring = "Μεταλλικα" #Metallica written in Greek letters
result = unistring[:1]
返回的结果是-> ?
我觉得unicode字符串是两个字节(字符),所以才会出现这种情况。如果我这样做:
result = unistring[:2]
我得到的结果是
M
这是正确的。那么,我是不是应该总是乘以2,还是说应该转换成其他格式呢?
3 个回答
对于任何类型的“Unicode字符串”,没有一种简单直接的方法。
即使是Python中的“Unicode” UTF-16字符串,它的字符长度也是不固定的,所以你不能简单地用ustring[:5]来截取前五个字符。因为有些Unicode代码点可能会用到多个“字符”,比如说“代理对”。
所以如果你想截取5个代码点(注意,这里说的是代码点,不是字符),你可能需要分析一下文本,可以参考http://en.wikipedia.org/wiki/UTF-8和http://en.wikipedia.org/wiki/UTF-16的定义。你需要使用一些位掩码来确定边界。
而且你仍然无法得到字符。举个例子,希伯来语的单词“שָלוֹם”(意为和平,发音为“Shalom”)由4个字符和6个代码点组成:字母“shin”、元音“a”、字母“lamed”、字母“vav”、元音“o”和最后的字母“mem”。
所以字符和代码点是不同的。
大多数西方语言也是如此,带有变音符号的字母可能会用两个代码点来表示。可以搜索一下“unicode normalization”。
所以……如果你真的需要前5个字符,你得使用像ICU库这样的工具。例如,Python中有一个ICU库,可以提供字符边界迭代器。
当你说:
unistring = "Μεταλλικα" #Metallica written in Greek letters
你并没有一个unicode字符串。你拥有的是一个字节串(通常是UTF-8格式)。这两者是不同的。unicode字符串在Python中是一个独立的数据类型。你可以通过使用正确的编码来解码字节串,从而得到unicode字符串:
unistring = "Μεταλλικα".decode('utf-8')
或者在源文件中使用unicode字面量,并且要有正确的编码声明
# coding: UTF-8
unistring = u"Μεταλλικα"
当你执行unistring[:5]
时,unicode字符串会按照你的想法工作。
很不幸的是,在Python 3.0之前,由于历史原因,字符串有两种类型:字节字符串(str
)和Unicode字符串(unicode
)。
在Python 3.0统一之前,有两种方式来声明字符串:unistring = "Μεταλλικα"
这是一个字节字符串,而unistring = u"Μεταλλικα"
是一个Unicode字符串。
当你执行 result = unistring[:1]
时看到 ?
,是因为你的Unicode文本中的某些字符在非Unicode字符串中无法正确表示。如果你曾经使用过非常老旧的邮件客户端,并收到来自希腊等国家朋友的邮件,你可能就遇到过这种问题。
所以在Python 2.x中,如果你需要处理Unicode,你必须明确地去做。可以看看这个关于如何处理Unicode的介绍:Unicode HOWTO