可选命名空间与方法时,捕获类名的正则表达式失效问题排查
正则匹配命名空间、类名和类方法的问题解决
问题根源
你修改后的正则(?<Namespace>[^@]*)?[\/]?(?<ClassName>[\w\d]*)@?(?<ClassMethod>[^@]*)?失效的核心原因是贪婪匹配的优先级冲突:
[^@]*是贪婪模式,会尽可能匹配所有非@的字符,当斜杠设为可选时,正则会优先把类名的字符归入Namespace分组,因为[\/]?可以选择不匹配,导致ClassName分组只能捕获空字符串。- 另外,
[\w\d]*允许匹配空字符串,进一步加剧了这个问题——正则认为ClassName可以为空,所以更倾向于把所有字符分给前面的Namespace。
正确的正则表达式
要实现「命名空间和类方法可选,类名必填」的需求,需要明确各部分的边界:
^(?:(?<Namespace>.+)\\)?(?<ClassName>\w+)(?:@(?<ClassMethod>.+))?$
规则说明
^(?:(?<Namespace>.+)\\)?:匹配命名空间部分,(?:...)是非捕获组,\\匹配命名空间末尾的斜杠,整个组可选(对应命名空间不存在的情况)。通过后面的\\和ClassName的边界限制,自动排除了@字符混入命名空间。(?<ClassName>\w+):匹配类名,\w+确保至少有一个字符(类名必填),包含字母、数字和下划线。(?:@(?<ClassMethod>.+))?$:匹配类方法部分,@作为分隔符,后面的.+匹配方法名,整个组可选。
测试验证
- 输入
Api\Blah\Blah\CarController@doStuff:- Namespace:
Api\Blah\Blah - ClassName:
CarController - ClassMethod:
doStuff
- Namespace:
- 输入
CarController:- Namespace: 空
- ClassName:
CarController - ClassMethod: 空
- 输入
Api\CarController:- Namespace:
Api - ClassName:
CarController - ClassMethod: 空
- Namespace:
- 输入
CarController@doStuff:- Namespace: 空
- ClassName:
CarController - ClassMethod:
doStuff
内容的提问来源于stack exchange,提问作者Samik Sengupta
相关产品推荐
相关产品推荐

