- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
= 2^16)代码点时截断 unicode 字符串的变通方法,我一直在使用一个小的 Python 方法逐步遍历字符串(记住,字符串是序列),确实ord() 在字-6ren">
作为 MySQL 在遇到“高”(序号 >= 2^16)代码点时截断 unicode 字符串的变通方法,我一直在使用一个小的 Python 方法逐步遍历字符串(记住,字符串是序列),确实ord() 在字符上,并通过替换其他内容或完全删除代码点来抢占截断。这在许多使用 Python 2.7.3 的机器上都按预期工作(Ubuntu 12.04 LTS,一些 Centos 6,混合 32 位和 64 位 CPU,到目前为止没有关系)。
我注意到在 Python 2.7.6 安装中,这会中断。 Ascii 字符和“低”代码点(序号 < 2^16)的行为与以前一样。但是高代码点 (>= 2^16) 的行为非常奇怪。 Python2.7.6 似乎将它们分别视为两个 代码点。这是一个归结为基础知识的测试用例:
### "good" machine, Python2.7.3
$ uname -a && echo $LANG
Linux *** 3.2.0-60-virtual #91-Ubuntu SMP Wed Feb 19 04:13:28 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
en_US.UTF-8
$ python2.7
Python 2.7.3 (default, Feb 27 2014, 19:58:35)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> utest = u'a\u0395\U0001f30e' # three chars: ascii, "low" codepoint, "high" codepoint
>>> utest.__class__
<type 'unicode'>
>>> len(utest), hash(utest)
(3, 1453079728409075183)
>>> list(utest) # split into list of single chars
[u'a', u'\u0395', u'\U0001f30e']
>>> utest[2] # trying to extract third char (high codepoint)
u'\U0001f30e'
>>> len(utest[2])
1
>>> "%x" % ord(utest[2])
'1f30e'
这是预期的行为。我用三个字符初始化一个 unicode 字符串。 Python 说它是三个字符,它可以很好地“寻址”第三个字符,返回单个预期的高代码点。如果我得到该代码点的序数,我会得到与原始转义序列中相同的数字。
现在是 Python 2.7.6
### "bad" machine, Python 2.7.6
$ uname -a && echo $LANG
Linux *** 2.6.32-431.5.1.el6.x86_64 #1 SMP Wed Feb 12 00:41:43 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
en_US.UTF-8
$ python2.7
Python 2.7.6 (default, Jan 29 2014, 20:05:36)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> utest = u'a\u0395\U0001f30e'
>>> utest.__class__
<type 'unicode'>
>>> len(utest), hash(utest) # !!!
(4, -2836525916470507760)
第一个差异:Python 2.7.6 说 utest 的长度为 4。哈希值也不同。下一个惊喜:
>>> list(utest) # !!!
[u'a', u'\u0395', u'\ud83c', u'\udf0e']
不仅长度表现得很奇怪,拆分成单个字符甚至更奇怪,因为高代码点的两个“一半”变成了两个没有明显数字关系的低代码点——至少对我来说——原始代码点。
通过序列索引寻址该代码点会出现相同的破损:
>>> utest[2]
u'\ud83c'
要获得原始的高代码点,我现在必须使用两个字符的切片:
>>> utest[2:4]
u'\U0001f30e'
但是,如果不是很明显的话,Python2.7.6 仍然在内部将其视为两个 代码点。我无法从中获得单个序数。
>>> len(utest[2:4])
2
>>> "%x" % ord(utest[2:4])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ord() expected a character, but string of length 2 found
那么,怎么办?我拥有的代码取决于 unicode 字符串中代码点的序数。如果一个代码点有时真的是两个代码点,我的序数就变得毫无意义,我的代码也无法执行它的功能。
这种行为有理由吗?是有意改动吗?是否有一些配置旋钮可以让我在 Python 内部或系统级别恢复旧行为?猴子补丁?我不知道去哪里看。
不幸的是,我什至无法将其缩小到确切的次要版本。我们安装了很多 2.7.3、一些 2.7.1 和几个 2.7.6。没有 2.7.4/2.7.5。我只能说我在任何 2.7.3 安装中都从未遇到过这个问题。
额外信息:将字符串编码为 utf8 会在两个 Python 版本中产生完全相同的响应(相同的字符、相同的长度、相同的散列)。再次解码编码为 utf8 的代码仍然会立即返回方 block 1(即,这不是解决方法,行为在 unicode 空间中仍然存在差异)。
最佳答案
您正在体验所谓的“代理对”。这些只发生在 narrow builds python,其中代码点在内部存储为 UTF-16。您可以通过检查 sys.maxunicode
(它将是 2**16 - 1)来确认您拥有哪个版本。
其他一些好的读物是 PEP 393 , 不幸的是,对于 python 3.3+,这使它停止了。
编辑:用谷歌搜索解决方法。 Full credit to @dan04 .
def code_points(text):
import struct
utf32 = text.encode('UTF-32LE')
return struct.unpack('<{}I'.format(len(utf32) // 4), utf32)
>>> len(utest)
4
>>> len(code_points(utest))
3
如果你只关心长度你可以做 len(utest.encode('UTF-32LE'))//4
,但看起来你想要做更多,所以也许上面的功能是有帮助的。
关于Python 2.7.6 将单个 "high"unicode 代码点一分为二,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22665667/
我正在尝试使用 double 来表示数据库中的一种双值类型,它有时必须接受两个值,有时只接受一个值 (int)。 所以该字段在数据库中是一个 float ,而在我的 C# 代码中,它是一个 doubl
假设我有一个带有非常快速测试脚本的小项目,我只想将所有内容一分为二,从初始提交到当前提交。我该怎么做? 澄清一下,我不想浪费时间来识别好提交和坏提交,所以我正在寻找一种快速方法来将最新提交标记为坏提交
我有这个代码 $second_half = $items; //ArrayIterator Object; $first_half = array_slice($second_half ,0,ceil
我正在尝试解析以字符串形式接收的二进制数据。我对按位运算不是很熟悉。 我的字符串中的一个字节(我假设它是一个无符号短整数)包含 2 个重要数字:版本和计数。位 1 到 4 包含版本,位 5 到 8 包
我想在点击某处时将 UITableView 分成两部分,顶部和底部。隐藏的部分将打开动画。谁能告诉我该怎么做? 这种效果就像在桌面上的 iOS 应用程序组中一样。 我认为“如何将 anyview 分成
我正在尝试拆分一个 TD(表格单元格),使其看起来就像是两个单元格。问题是,当单元格的高度增长时,我无法让里面的两个 div 占据所有可用的高度。由于这些单元格可以动态增长,我也无法设置固定高度(这可
我有一个很大的代码差异需要审查,但它确实应该分成两个单独的差异。 每个差异都有很多提交,我可以找出哪一个(大部分)将提交字符串拆分为两个不同的任务,尽管更清晰的拆分将基于文件名(即 N 个文件与 w/
我如何将一个数据帧除以另一个?这两个数据框具有相同的列和相同的行,但我需要将每个相交与其对应的相交划分为一个新的数据框,例如以下: DF1 Name Jan Feb Mar Aaro
我编写了一个 MFC 程序来读取文件、存储数据并将其绘制为客户端 View 上的文本。 我想制作一个菜单按钮 View->Split,将客户区分成两个,分别滚动显示相同数据的 View 。 我在网上看
我试图在一个页面上放置两个注册表单,但为了有效地执行此 id,我想将中心 div 分成两个单独的列来实现此目的。 我贴出了下面的代码:
是否有一种简单且运行时高效的方法可以在 C++ 中采用 std::vector<> 并将其分成两半分成另外两个 vector ? 因为现在我正在这样做: std::vector<> v1, v2; f
问题 我想将 pandas 数据框中的一列拆分为 2 列,在百分比列(见下文)中,每个条目都以大写字母字符开头,我想在这封信之后立即拆分“百分比”列,新列标记为“氨基酸”。 当前代码: import
我正在尝试将一个 div 分成两个并排的 div。我知道这里有几个例子,但我已经搜索过但没有找到一个允许 div 在垂直方向占用所有可用空间,没有任何内容。 看看http://jsfiddle.net
我有一个数据框: col_1 Agent AB 7:00 AM Agent AB 7:00 AM Cust XY 8:00 AM Cust XY 9:00 AM Agent AB 11:00 AM 我
我正在使用 C# 和 ASP.NET 3.5。基本上我从数据集中检索一列数据并将其放入列表中,如下所示: List dates = new List(); foreach (DataR
我想将我的 div“划分”为两部分,以便在左侧显示文本,在右侧显示图像。关于主题中提到的 div 具有橙色背景色和红色线条。这只是为了向您展示它应该是什么样子。 HTML #header { he
我正在尝试将一串文本分成两半,注意不要: 断词 破坏 html 为了给你一些背景知识,我想拍一篇博客文章并在其中插入一个广告。 我四处寻找答案,但我在 SO 上能找到的唯一选项建议剥离所有 HTML—
我需要用 JQuery 将一个列表分成两部分。假设我有以下列表: item item item item item 我试过使用: $("li#POI").after("");
我正在使用一个画廊,它代表一个包含一个或两个的列 跨越整个宽度的元素。包含多个 的列元素还包含具有不同高度和宽度属性的图像。我希望这些列具有相同的高度,然后在它们之间有额外空间时尽可能填充宽度。 我
我是一名优秀的程序员,十分优秀!