我有以下标识符的定义:
Identifier --> letter{ letter| digit}
字符串
基本上,我有一个标识符函数,它从文件中获取一个字符串,并测试它,以确保它是一个有效的标识符,如上所述。
我试过这个:
if re.match('\w+(\w\d)?', i):
return True
else:
return False
型
但是当我运行我的程序时,每次遇到一个整数,它都认为这是一个有效的标识符。
比如说
c = 0 ;
型
它打印c
作为有效标识符,这很好,但它也打印0
作为有效标识符。
我做错什么了?
7条答案
按热度按时间vu8f3i0k1#
这个问题是在10年前提出的,当时Python 2仍然占主导地位。正如过去十年中的许多评论所表明的那样,我的回答需要认真更新,从一个大的头开始:
**没有一个正则表达式可以正确匹配所有(并且只有)有效的Python标识符。Python 2没有,Python 3也没有。
原因是:
True
,if
,return
,是不是有效的标识符,而正则表达式本身无法处理这一点,因此需要额外的过滤。re
模块中的\d
,\w
,\W
的相同类别不匹配,如@martineau的反例所示,并由@Hatshepsut的amazing research详细解释。虽然我们可以尝试使用
keyword.iskeyword()
来解决第一个问题,正如@ Alexandria Huszagh所建议的那样,并通过限制仅使用ascii标识符来解决另一个问题,但为什么要使用正则表达式呢?正如哈特谢普苏特所说:
**
str.isidentifier()
**工作使用它,问题就解决了。
根据问题的要求,我在2012年的原始答案给出了一个基于Python 2官方定义的正则表达式:
字符串
它可以用正则表达式表示:
型
范例:
型
测试结果:
型
qco9c6ql2#
**
str.isidentifier()
**工作。正则表达式的答案不正确地无法匹配一些有效的Python标识符,并且不正确地匹配一些无效的标识符。str.isidentifier()
根据语言定义、部分标识符和关键字,如果字符串是有效标识符,则返回true。使用
keyword.iskeyword()
测试保留的标识符,如def和class。@martineau的评论给出了
'℘᧚'
的例子,其中regex解决方案失败。字符串
为什么会这样?
让我们定义匹配给定正则表达式的代码点集,以及匹配
str.isidentifier
的代码点集。型
有多少正则表达式匹配不是标识符?
型
有多少标识符不是正则表达式匹配?
型
有意思,是哪几个
型
这两套有什么不同?
它们具有不同的Unicode“通用类别”值。
型
从维基百科上看,是
Letter, modifier
;Letter, other
;Number, other
。这与re docs一致,因为\d
只是十进制数字:\d
匹配任何Unicode十进制数字(即Unicode字符类别[Nd]中的任何字符)那另一条路呢
型
这是
Mark, nonspacing
;Symbol, math
;Symbol, other
的值。这些都记录在哪里?
在哪里实现?
https://github.com/python/cpython/commit/47383403a0a11259acb640406a8efc38981d2255的
我还是要正则表达式
查看PyPI上的regex模块。
这个正则表达式实现与标准的're'模块向后兼容,但提供了额外的功能。
它包括“一般类别”的过滤器。
ruyhziif3#
对于Python 3,您需要处理Unicode字母和数字。所以如果这是一个问题,你应该这样沿着:
字符串
[^\d\W]
匹配的字符不是数字,也不是“非字母数字”,即“字母或下划线字符”。3df52oht4#
\w匹配数字和字符。试试
^[_a-zA-Z]\w*$
rsl1atfo5#
这个问题是关于正则表达式的,所以我的回答可能会偏离主题。关键是regex不是正确的方法。
使用
str.isidentifier
,可以逐个字符地执行检查,例如,用下划线作为前缀以避免误报,例如数字等。如果一个名字的(前缀)成分之一不是(?))例如:个字符
哪种解决方案处理未经授权的第一个字符,如数字或例如
᧚
,参见型
需要改进的是,它既不检查保留名称,也不告诉任何关于为什么
᧚
有时会有问题,而₂
总是有问题。但这里是我的无正则表达式方法。型
可以收缩成
型
ve7v8dk26#
我需要一个工作正则表达式(即我不能只使用
str.isidentifier
),因为我需要找到嵌入在字符串中的所有标识符,而不仅仅是测试整个字符串是否是有效的标识符。我也不能使用ast
模块,因为我希望字符串不是有效的Python语法。所以现有的答案没有帮助,我不满意“使用正则表达式包”。下面是一个真正的正则表达式,它完成了这项工作,沿着还有构造和测试它的代码。字符串
7vux5j2d7#
工作起来很有魅力:第一个月