解析Java正则表达式(?<=(.))(?!\1),请求帮助拆解说明
拆解正则表达式
(?<=(.))(?!\1) 的原理 嘿,作为正则新手能靠自己写出解决问题的表达式已经很棒了!我来帮你把这个正则拆解得明明白白,重点讲你困惑的(?!\1)部分~
先明确整个正则的作用
这个表达式其实是用来匹配两个相邻不同字符之间的位置(注意是“位置”,不是字符本身)。比如在字符串"aabcc"里,它会匹配aa和b之间、b和cc之间的两个间隙。
逐部分拆解
1. (?<=(.)):正向后瞻捕获
你已经知道(?<=...)是正向预查(准确来说叫正向后瞻,用来匹配某个位置的“前面”符合条件),里面的(.)是一个捕获组:
(.):匹配任意单个字符(默认不包含换行符,若开启单行模式则包含),并且把这个字符存入捕获组1,后续可以用\1来引用这个捕获到的字符。- 所以
(?<=(.))的意思是:找到一个位置,这个位置的前一个字符是任意字符,同时我们把这个前字符存下来备用。
2. (?!\1):负向前瞻排除
这就是你困惑的部分啦:
(?!...)是负向前瞻,它的作用是“确保当前位置的后面不符合括号里的条件”,如果后面符合条件,整个匹配就失败。\1是对前面捕获组1的引用,也就是刚才(?<=(.))里捕获到的那个前字符。- 所以
(?!\1)的意思是:当前位置的后面不能是之前捕获到的那个前字符。
结合起来理解
把两部分拼在一起,整个正则的逻辑就是:
找一个位置,它的前面是某个字符X,同时它的后面不是X → 也就是相邻两个不同字符之间的间隙。
举个具体的例子,拿字符串"aabbbcc"来说:
- 第一个
a和第二个a之间:前面是a(\1=a),后面也是a,(?!\1)不满足,不匹配这个位置; - 第二个
a和第一个b之间:前面是a(\1=a),后面是b≠a,满足所有条件,匹配这个位置; - 第一个
b和第二个b之间:前面是b(\1=b),后面是b,不满足,不匹配; - 第三个
b和第一个c之间:前面是b(\1=b),后面是c≠b,满足条件,匹配这个位置; - 第一个
c和第二个c之间:前面是c,后面是c,不满足,不匹配。
这样是不是就完全清楚啦?
内容的提问来源于stack exchange,提问作者D. Thornley
相关产品推荐
相关产品推荐

