4

我正在匹配标识符,但现在我遇到了一个问题:我的标识符允许包含 unicode 字符。因此,旧的做事方式是不够的:

t_IDENTIFIER = r"[A-Za-z](\\.|[A-Za-z_0-9])*"

我的标记语言解析器中,我通过允许除我明确使用的字符之外的所有字符来匹配 unicode 字符,因为我的标记语言只有两个或三个我需要以这种方式转义的字符。

如何将所有 unicode 字符与 python 正则表达式和 ply 匹配?这也是一个好主意吗?

我想让人们在他们的程序中使用像 Ω » « ° foo² väli π 这样的标识符作为标识符(变量名等)。见鬼!如果可行,我希望人们可以用自己的语言编写程序!无论如何,如今在很多地方都支持 unicode,它应该传播开来。

编辑:python 正则表达式似乎无法识别 POSIX 字符类。

>>> import re
>>> item = re.compile(r'[[:word:]]')
>>> print item.match('e')
None

编辑:为了更好地解释我需要什么。我需要一个匹配所有 unicode 可打印字符但根本不匹配 ASCII 字符的正则表达式。

编辑: r"\w" 做了一些我想要的东西,但它不匹配« »,我还需要一个不匹配数字的正则表达式。

4

5 回答 5

5

re模块支持\w 语法:

如果设置了 UNICODE,这将匹配字符 [0-9_] 加上 Unicode 字符属性数据库中分类为字母数字的任何内容。

因此,以下示例显示了如何匹配 unicode 标识符:

>>> import re
>>> m = re.compile('(?u)[^\W0-9]\w*')
>>> m.match('a')
<_sre.SRE_Match object at 0xb7d75410>
>>> m.match('9')
>>> m.match('ab')
<_sre.SRE_Match object at 0xb7c258e0>
>>> m.match('a9')
<_sre.SRE_Match object at 0xb7d75410>
>>> m.match('unicöde')
<_sre.SRE_Match object at 0xb7c258e0>
>>> m.match('ödipus')
<_sre.SRE_Match object at 0xb7d75410>

所以你要找的表达式是: (?u)[^\W0-9]\w*

于 2008-10-26T21:18:53.630 回答
4

您需要在 lex.lex 中传递传递参数重新标记:

lex.lex(reflags=re.UNICODE)
于 2011-12-14T10:26:38.087 回答
1

检查这个问题的答案

从python中的字符串中去除不可打印的字符

您只需要改用其他 unicode 字符类别

于 2008-10-26T16:58:56.370 回答
1

在 Vinko 的帮助下解决了这个问题。

我意识到获取 unicode 范围是愚蠢的。所以我会这样做:

symbols = re.escape(''.join([chr(i) for i in xrange(33, 127) if not chr(i).isalnum()]))
symnums = re.escape(''.join([chr(i) for i in xrange(33, 127) if not chr(i).isalnum()]))

t_IDENTIFIER = "[^%s](\\.|[^%s])*" % (symnums, symbols)

我不知道 unicode 字符类。如果这个 unicode 的东西开始变得太复杂,我可以把原来的东西放好。UTF-8 支持仍然确保支持在 STRING 令牌上,这是更重要的。

编辑:另一方面,我开始理解为什么编程语言中没有太多的 unicode 支持。这是一个丑陋的黑客,不是一个令人满意的解决方案。

于 2008-10-26T17:19:46.903 回答
0

可能POSIX 字符类适合您?

于 2008-10-26T16:37:58.737 回答