python 返回 unicode 字符串的前 N ​​个字符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2153920/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 23:55:10  来源:igfitidea点击:

Returning the first N characters of a unicode string

pythonunicodepython-2.x

提问by Jon Romero

I have a string in unicode and I need to return the first N characters. I am doing this:

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

result = unistring[:5]

but of course the length of unicode strings != length of characters. Any ideas? The only solution is using re?

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

Edit: More info

编辑:更多信息

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

returns-> ?

返回-> ?

I think that unicode strings are two bytes (char), that's why this thing happens. If I do:

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

result = unistring[:2]

I get

我得到

M

M

which is correct, So, should I always slice*2 or should I convert to something?

这是正确的,那么,我应该总是切片 *2 还是应该转换为某些东西?

采纳答案by Tendayi Mawushe

Unfortunately for historical reasons prior to Python 3.0 there are two string types. byte strings (str) and Unicode strings (unicode).

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

Prior to the unification in Python 3.0 there are two ways to declare a string literal: unistring = "Μεταλλικα"which is a byte string and unistring = u"Μεταλλικα"which is a unicode string.

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

The reason you see ?when you do result = unistring[:1]is because some of the characters in your Unicode text cannot be correctly represented in the non-unicode string. You have probably seen this kind of problem if you ever used a really old email client and received emails from friends in countries like Greece for example.

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

So in Python 2.x if you need to handle Unicode you have to do it explicitly. Take a look at this introduction to dealing with Unicode in Python: Unicode HOWTO

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

回答by Thomas Wouters

When you say:

当你说:

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

You do not havea unicode string. You have a bytestring in (presumably) UTF-8. That is not the same thing. A unicode string is a separate datatype in Python. You get unicode by decoding bytestrings using the right encoding:

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

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

or by using the unicode literal in a source file with the right encoding declaration

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

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

The unicode string will do what you want when you do unistring[:5].

unicode 字符串将在您执行时执行您想要的操作unistring[:5]

回答by Artyom

There is no correct straight-forward approach with any type of "Unicode string".

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

Even Python "Unicode" UTF-16 string has variable length characters so, you can't just cut with ustring[:5]. Because some Unicode Code points may use more then one "character" i.e. Surrogate pairs.

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

So if you want to cut 5 code points(note these are not characters) so you may analyze the text, see http://en.wikipedia.org/wiki/UTF-8and http://en.wikipedia.org/wiki/UTF-16definitions. So you need to use some bit masks to figure out boundaries.

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

Also you still do not get characters. Because for example. Word "??????" -- peace in Hebrew "Shalom" consists of 4 characters and 6 code points letter "shin", vowel "a" letter "lamed", letter "vav" and vowel "o" and final letter "mem".

你仍然没有得到字符。因为例如。单词 ”??????” -- 希伯来语“Shalom”中的和平由 4 个字符和 6 个代码点字母“shin”、元音“a”字母“lamed”、字母“vav”和元音“o”以及最后一个字母“mem”组成。

So characteris not code point.

所以字符不是代码点

Same for most western languages where a letter with diacritics may be represented as two code points. Search for example for "unicode normalization".

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

So... If you really need 5 first characters you have to use tools like ICU library. For example there is ICU library for Python that provides characters boundary iterator.

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