如何编写正则表达式匹配Python 3合法Unicode变量名?
匹配Python 3合法变量名的正则表达式
首先直接给结论:Python的re模块里的\w无法覆盖所有合法的Python 3变量名,比如像∑、α这类数学符号变量名,\w就匹配不到。要写出能准确匹配所有Python 3合法变量名的正则,得从Python官方的标识符规则入手。
Python 3变量名的核心规则
Python 3对标识符(变量名属于标识符)的规则是:
- 必须以Unicode XID_Start类别的字符开头:包括所有语言的Unicode字母、下划线
_,以及部分特殊字符(比如罗马数字Ⅸ、数学符号∑这类符合标识符规范的符号) - 后续字符可以是Unicode XID_Continue类别的字符:涵盖XID_Start的所有字符,加上数字、变音符号等符合规范的字符
正确的正则表达式
在Python 3.6及以上版本(现在主流版本都满足),可以直接用Unicode属性转义来写出精准匹配的正则:
import re pattern = r'^[\p{XID_Start}][\p{XID_Continue}]*$' # 测试示例 test_names = ["var123", "_private", "ñombre", "∑total", "α_value", "123invalid"] for name in test_names: print(f"{name}: {'合法' if re.match(pattern, name) else '不合法'}")
这个正则完全遵循Python 3的标识符规范,能匹配所有合法变量名,同时排除像以数字开头的非法变量名。
为什么\w不够用?
Python的re模块中,\w默认匹配的是Unicode中的字母(L)、数字(N)、下划线(Pc),但Python 3允许的变量名还包含一些属于**数学符号(Sm)**等类别的字符(比如∑),这些字符不在\w的匹配范围内,所以用\w写的正则会漏掉这类合法变量名。
旧版本Python的替代方案
如果还在使用Python 3.5及以下版本(不支持Unicode属性转义),可以结合unicodedata模块来判断字符是否符合XID规则,不过这种场景下用正则就不如直接写判断函数来得可靠了:
import unicodedata def is_valid_variable_name(name): if not name: return False # 验证首字符是否符合XID_Start规则 start_categories = ('Lu', 'Ll', 'Lt', 'Lm', 'Lo', 'Nl', 'Pc') if unicodedata.category(name[0]) not in start_categories: return False # 验证后续字符是否符合XID_Continue规则 continue_categories = start_categories + ('Nd', 'Mn', 'Mc', 'Cf') for char in name[1:]: if unicodedata.category(char) not in continue_categories: return False return True
这个函数模拟了XID_Start和XID_Continue的判断逻辑,能准确验证变量名是否合法。
内容的提问来源于stack exchange,提问作者jmd_dk
相关产品推荐
相关产品推荐

