Perl正则匹配任意顺序大小写含wizard全部字符的代码问题排查
问题分析
第一个正则的错误
你写的第一个正则是/(?:([wizard])(?!.*\1)){6}/i,核心问题是:
正则要求6个符合条件的字符必须连续排列:(?:...){6}结构会要求6次匹配的字符是连续的,每匹配一个字符就会向后移动一个位置,不能跳过无关字符,而你的输入里符合要求的字符都是散布的,不存在连续6个都属于w/i/z/a/r/d集合的内容,自然匹配失败。
第二个正则的错误
你修改后的正则/(?=[wizard]{6})(?!.*(.).*\1).*/i存在两个明显问题:
- 正向预查
(?=[wizard]{6})要求当前位置后面存在连续6个都属于w/i/z/a/r/d集合的字符,你的所有输入都不满足这个条件,预查直接失败,自然不会匹配。 - 负向预查
(?!.*(.).*\1)要求整个字符串里没有任何重复字符,你的第4个输入里有两个a,就算前一个条件满足,这个预查也会失败,完全不符合你的需求。
正确实现方案
如果坚持用正则实现,可以用6个独立的正向预查,分别判断每个字符存在即可,代码示例:
while(<>){if($_=~/^(?=.*w)(?=.*i)(?=.*z)(?=.*a)(?=.*r)(?=.*d).*/i){print"0"}else{print"1"}}
这个写法的逻辑是分别检查字符串里存在w、i、z、a、r、d(不区分大小写),不需要连续,不需要固定顺序,完全符合你的需求,测试第4个输入就会正确输出0。如果追求更高的执行效率,也可以用哈希表统计字符出现次数的方法实现,不需要依赖正则。
内容的提问来源于stack exchange,提问作者Suzuna Minami
相关产品推荐
相关产品推荐

