11

我有一个 unicode 字符串,我需要返回前 N 个字符。我正在这样做:

result = unistring[:5]

但当然是 unicode 字符串的长度!= 字符的长度。有任何想法吗?唯一的解决方案是使用 re?

编辑:更多信息

unistring = "Μεταλλικα" #Metallica written in Greek letters
result = unistring[:1]

返回->?

我认为 unicode 字符串是两个字节(char),这就是发生这种情况的原因。如果我做:

result = unistring[:2]

我明白了

M

这是正确的,那么,我应该总是切片 *2 还是应该转换成什么?

4

3 回答 3

7

当你说:

unistring = "Μεταλλικα" #Metallica written in Greek letters

没有unicode 字符串。您在(大概)UTF-8 中有一个字节串。那不是一回事。Unicode 字符串是 Python 中的一种单独的数据类型。您可以通过使用正确的编码解码字节串来获得 unicode:

unistring = "Μεταλλικα".decode('utf-8')

或者通过在具有正确编码声明的源文件中使用 unicode 文字

# coding: UTF-8
unistring = u"Μεταλλικα"

unicode 字符串会做你想做的事unistring[:5]

于 2010-01-28T12:44:50.860 回答
7

不幸的是,由于 Python 3.0 之前的历史原因,有两种字符串类型。字节字符串 ( str) 和 Unicode 字符串 ( unicode)

在 Python 3.0 统一之前,有两种方法可以声明字符串文字:unistring = "Μεταλλικα"一种是字节字符串,unistring = u"Μεταλλικα"一种是 unicode 字符串。

您看到的原因是?result = unistring[:1]的 Unicode 文本中的某些字符无法在非 Unicode 字符串中正确表示。如果您曾经使用过非常旧的电子邮件客户端并收到来自希腊等国家/地区的朋友的电子邮件,您可能已经看到过这种问题。

因此,在 Python 2.x 中,如果您需要处理 Unicode,您必须明确地进行处理。看看这篇关于在 Python 中处理 Unicode 的介绍:Unicode HOWTO

于 2010-01-28T14:03:48.253 回答
4

对于任何类型的“Unicode 字符串”,都没有正确的直接方法。

甚至 Python "Unicode" UTF-16 字符串也有可变长度的字符,所以你不能只用 ustring[:5] 剪切。因为某些 Unicode 代码点可能使用多个“字符”,即代理对。

因此,如果您想削减 5 个代码点(注意这些不是字符)以便分析文本,请参阅http://en.wikipedia.org/wiki/UTF-8http://en.wikipedia.org/ wiki/UTF-16定义。所以你需要使用一些位掩码来找出边界。

此外,您仍然没有得到字符。因为例如。单词“שָלוֹם”——希伯来语中的和平“Shalom”由 4 个字符和 6 个代码点字母“shin”、元音“a”字母“lamed”、字母“vav”和元音“o”以及最后一个字母“mem”组成。

所以字符不是代码点

大多数西方语言也是如此,其中带有变音符号的字母可以表示为两个代码点。搜索例如“unicode normalization”。

所以...如果你真的需要 5 个第一个字符,你必须使用 ICU 库之类的工具。例如,Python 的 ICU 库提供了字符边界迭代器。

于 2010-01-29T13:39:24.833 回答