涉及星体平面的unicode范围的Python语义

2024-09-30 16:40:50 发布

您现在位置:Python中文网/ 问答频道 /正文

如果正则表达式中字符范围的一个或两个端点都在BMP之外,那么它的预期语义到底是什么?我观察到以下输入在Python 2.7和3.5中的行为不同:

import re
bool(re.match(u"[\u1000-\U00021111]", "\u1234"))

在我的2.7中我得到False,在3.5中我得到True。后者对我来说是有意义的。前者可能是由于\U00021111由一个代理项对\ud844\udd11表示,但即使这样,我也不理解,因为{}应该包括{}很好。在

  • 这是在什么地方指定的吗?在
  • 这是故意的行为吗?在
  • 这仅仅取决于Python版本,还是取决于关于UTF-16和UTF-32的编译时标志?在
  • 有没有一种方法可以在不区分案例的情况下获得一致的行为?在
  • 如果区分案件是不可避免的,那么具体的条件是什么?在

Tags: importrefalsetruematch语义端点字符
2条回答

这是我目前发现的情况。在

python2.2接受的PEP 261引入了一个编译时标志,用窄的UTF-16表示或宽的UTF-32字符表示来构建unicode支持。选中hex(sys.maxunicode)或{}以在运行时区分这些:窄构建将报告最大值0xffff和长度{},wide构建最大值为0x10ffff,长度为{}。^python3.3的{a2}隐藏了unicode字符串的实现细节,使所有字符串看起来都像UTF-32(除非必要,否则实际上不会浪费太多空间)。因此,3.3之前的窄版本将把星体平面上的代码点分解为代理项对,并独立地处理各个代理项,以便构造正则表达式和匹配的字符串。或者至少我找不到相反的迹象。在

正如Wiktor所指出的,我的例子非常愚蠢,因为我忘记了第二个字符串文本的u前缀。因此,Python2不会将其解析为转义序列,而是将其解析为字节字符串。这就解释了为什么即使考虑了代理项对,代码点似乎也不在这个范围内。在

至于预期的行为:自从python3.3以来,基于构建类型的区分应该已经过时了。将每个代码点视为一个单元,无论平面如何,这应该是Python3的前进方向。但是窄版本上的向后兼容性对旧版本来说是一个矛盾的目标。在

只需将u前缀与输入字符串一起使用,告诉Python它是一个Unicode字符串:

>>> bool(re.match(u"[\u1000-\U00021111]", u"\u1234")) # <= See u"\u1234"
True

在Python2.7中,每次处理字符串时都需要将其解码为Unicode。在python3中,默认情况下所有字符串都是Unicode,并且在docs中声明。在

相关问题 更多 >