gpt4 book ai didi

Python unicode 正则表达式匹配因某些 unicode 字符而失败 - 错误或错误?

转载 作者:太空狗 更新时间:2023-10-29 20:17:17 24 4
gpt4 key购买 nike

我正在尝试使用 Python 2.7.3 中的 re 模块和 Unicode 编码的 Devnagari 文本。我已将 from __future__ import unicode_literals 添加到我的代码顶部,因此所有字符串文字都应该是 unicode 对象。

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

以下返回匹配项,因为它应该:

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

但这不是:

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

一些 spelunking 揭示了这个字符串中只有一个字符,字符 0915 (क),被识别为属于\w 字符类。这是不正确的,因为 Unicode 字符数据库 file on "derived core properties"将此字符串中的其他字符(我没有全部检查)列为字母字符 - 事实上它们确实如此。

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

最佳答案

这是一个bug in the re module它固定在 regex module 中:

# -*- 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 Text Segmentation说:

Word boundaries, line boundaries, and sentence boundaries should not occur within a grapheme cluster: in other words, a grapheme cluster should be an atomic unit with respect to the process of determining these other boundaries.

这里和进一步强调是我的

单词边界 \b 被定义为在 the docs 中从 \w\W(或相反)的转换:

Note that formally, \b is defined as the boundary between a \w and a \W character (or vice versa), or between \w and the beginning/end of the string, ...

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


来自 the docs for \w in Python 2 :

If UNICODE is set, this will match the characters [0-9_] plus whatever is classified as alphanumeric in the Unicode character properties database.

Python 3 :

Matches Unicode word characters; this includes most characters that can be part of a word in any language, as well as numbers and the underscore.

来自 regex 文档:

Definition of 'word' character (issue #1693050):

The definition of a 'word' character has been expanded for Unicode. It now conforms to the Unicode specification at http://www.unicode.org/reports/tr29/. This applies to \w, \W, \b and \B.

根据 unicode.org U+093F (DEVANAGARI VOWEL SIGN I)是 alnum 和字母顺序,所以 regex 也是正确的考虑它 \w 即使我们遵循不基于单词边界的定义。

关于Python unicode 正则表达式匹配因某些 unicode 字符而失败 - 错误或错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12746458/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com