这是模块中的一个错误,它已在re
模块中修复:regex
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import unicodedata
import re
import regex # $ pip install regex
word = "किशोरी"
def test(re_):
assert re_.search("^\\w+$", word, flags=re_.UNICODE)
print([unicodedata.category(cp) for cp in word])
print(" ".join(ch for ch in regex.findall("\\X", word)))
assert all(regex.match("\\w$", c) for c in ["a", "\u093f", "\u0915"])
test(regex)
test(re) # fails
输出显示 中有 6 个代码点"किशोरी"
,但只有 3 个用户感知字符(扩展字形簇)。在一个字符内打断一个单词是错误的。 Unicode 文本分割说:
单词边界、行边界和句子边界不应出现在字素簇内:换句话说,就确定这些其他边界的过程而言,字素簇应该是一个原子单元。
在这里,进一步强调是我的
单词边界在文档\b
中定义为从\w
到\W
(或反向)的转换:
请注意,正式地,\b 被定义为 \w 和 \W 字符之间的边界(反之亦然),或 \w 和字符串的开头/结尾之间,...
因此,形成单个字符的所有代码点要么是,要么\w
都是\W
. 在这种情况下"किशोरी"
匹配^\w{6}$
.
来自Python 2 中的文档\w
:
如果设置了 UNICODE,这将匹配字符 [0-9_] 加上Unicode 字符属性数据库中分类为字母数字的任何内容。
在Python 3中:
匹配 Unicode 单词字符;这包括可以成为任何语言中单词一部分的大多数字符,以及数字和下划线。
来自regex
文档:
'word' 字符的定义(问题 #1693050):
“单词”字符的定义已针对 Unicode 进行了扩展。它现在符合
http://www.unicode.org/reports/tr29/上的 Unicode 规范。这适用于 \w、\W、\b 和 \B。
根据unicode.org U+093F
( DEVANAGARI VOWEL SIGN I
)是 alnum 和 alphabetic 因此即使我们遵循不基于单词边界的定义,regex
考虑它也是正确的。\w