Python unicode正则表达式与某些unicode字符匹配失败-错误还是错误?

Python unicode正则表达式与某些unicode字符匹配失败-错误还是错误?,python,regex,unicode,Python,Regex,Unicode,我正在尝试将Python 2.7.3中的re模块与Unicode编码的Devnagari文本一起使用。我已经在我的代码顶部添加了来自“未来导入unicode”文本的,因此所有字符串文本都应该是unicode对象 然而,我在Python的正则表达式匹配方面遇到了一些奇怪的问题。例如,考虑这个名字:किशोरी". 这是一个(拼写错误的)印地语名字,由我的一个用户输入。任何印地语读者都会认出这是一个单词 以下内容将返回一个匹配项,正如它应该返回的那样: re.search(“^[\w\s][\w\

我正在尝试将Python 2.7.3中的
re
模块与Unicode编码的Devnagari文本一起使用。我已经在我的代码顶部添加了来自“未来导入unicode”文本的
,因此所有字符串文本都应该是unicode对象

然而,我在Python的正则表达式匹配方面遇到了一些奇怪的问题。例如,考虑这个名字:किशोरी". 这是一个(拼写错误的)印地语名字,由我的一个用户输入。任何印地语读者都会认出这是一个单词

以下内容将返回一个匹配项,正如它应该返回的那样:

re.search(“^[\w\s][\w\s]*”,“किशोरी“,关于UNICODE)

但这并不是:

re.search(“^[\w\s][\w\s]*$”किशोरी“,关于UNICODE)

一些洞穴探险发现这个字符串中只有一个字符,字符0915(क), 被识别为属于\w字符类。这是不正确的,因为Unicode字符数据库将此字符串中的其他字符(我没有全部选中)按字母顺序列出-事实上是这样的

这只是Python实现中的一个bug吗?我可以通过手动将所有Devnagari字母数字字符定义为一个字符范围来解决这个问题,但这会很痛苦。或者我做错了什么吗?

来自character Map:

‍ि

U+093F DEVANAGARI元音符号I

一般字符特性

从1.1开始使用Unicode Unicode类别:标记,空格组合


因此,从技术上讲,这不是一个字母,即使使用
re.UNICODE
,也不属于
\w
。您可以尝试使用with UNICODE字符属性来包含这些类型的字符。

我测试了以下内容:

import unicodedata
for c in "किशोरी":
    print unicodedata.category(c)
    print unicodedata.name(c)
在我的案例中显示:

Lo
DEVANAGARI LETTER KA
Mc
DEVANAGARI VOWEL SIGN I
Lo
DEVANAGARI LETTER SHA
Mc
DEVANAGARI VOWEL SIGN O
Lo
DEVANAGARI LETTER RA
Mc
DEVANAGARI VOWEL SIGN II
Unicode的东西很难调试,因为复制和粘贴会弄乱数据,我不懂印地语。但是在某些语言中,你可以用Unicode以不同的方式编码字符。有没有可能,在匹配之前,你必须以某种方式对字符串进行规范化?在我看来,元音符号与
\w
不匹配是正常的d固定在以下位置:

输出显示
中有6个代码点。”किशोरी“
,但只有3个用户感知的字符(扩展的字组)。在字符中打断一个单词是错误的。表示:

单词边界、行边界和句子边界不应 发生在一个grapheme集群中:换句话说,一个grapheme集群 就测定过程而言,应为原子单位 这些是其他边界

我在此进一步强调

单词边界
\b
定义为从
\w
\w
(或相反)的转换:

请注意,形式上,\b定义为a\w和a之间的边界 \W个字符(反之亦然),或介于\W和 字符串

因此,形成单个字符的所有代码点要么都是
\w
,要么都是
\w
。 在这种情况下,
”किशोरी“
匹配
^\w{6}$


发件人:

如果设置了UNICODE,则这将与字符[0-9_u2;]加匹配 在Unicode字符中分类为字母数字的内容 属性数据库

在:

匹配Unicode单词字符;这包括 可以是任何语言中单词的一部分,也可以是数字和 下划线

regex
文档:

“word”字符()的定义:

“word”字符的定义已扩展为Unicode。它现在符合 。这适用于\w、\w、\b和 \B


根据AlnUM和字母SuxEng/ReXEX/COD>也可以正确地考虑它<代码> \W>代码>即使我们遵循不基于单词边界的定义。

根据093F确实被分类为字母字符。不确定发生了什么。无论如何,这些都必须被识别为这些字符。s从不独立存在,它们是对现有字符的修改,以表示特定的元音(在本例中,该字符表示后续的“ka”应发音为“ki”)。如果要拒绝将这些字符和类似字符作为字母字符,则在使用它的任何语言中都不能使用Devnagari文本(印地语、孟加拉语、马拉地语等)在本质上是按字母顺序排列的。“093E..0940;字母顺序的#Mc[3]德瓦纳加里元音符号AA..DEVANAGARI元音符号II”Mc.Mc.什么是“Mc?”"意思是什么?它不是也说字母吗?它是字母,但不是字母。请看下面对Ignacio答案的评论。不过,你说的规范化是什么意思?也许这样就可以了。我不记得我脑子里的确切细节,但有一个字符是独立存在的,也可以是一个字母组合。例如德语
ä
。这是一个单独的字符,但据我所知,有可能将其编码为
一个
+
标记,以便在上面有那些点
。两个版本之间都有转换。抱歉,我目前无法检查详细信息。是的,可以确认regex模块工作正常。[:alnum:]POSIX字符类也适用于正则表达式模块。@ShankarG:
perl
agreements:
echoकिशोरी | perl-CS-ne'print if/^\w+$/'
(假设为utf-8 io)。将我的“接受”标记更改为此答案,因为这实际上是正确的答案-这确实是re模块中的一个错误。
# -*- 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