正则表达式这个语法以简单高效著称,但是有一点i就是比较复杂。
近期有个功能需要去除字符串中重复的部分,由于使用正常的传统的那种舒服拆分成数组在一个一个匹配的方式感觉有点效率过低浪费性能,于是便想到了正则表达式来匹配重复的字符串,并利用String自导的replaceAll方法来将相应的字符串给删除掉。
目标字符串:
"10110,10254,10554,11025,10254,11002,11532,10110,";
这是一个数字数组,但是这里面有某些ID是重复的,我必须将之去除掉。由于我对正则语法实在不熟悉,都是临时对着说明文档在使用的阶段。没有比较好的思路,所以去网上查了些思路。
发现一个类似的解决方案,去除重复的字母具体代码如下:
String str = "aaaaaaahdbkjsdnfkjsndjkfsdfsdf";
str = str.replaceAll("(?s)(.)(?=.*\\1)", "");
System.out.println(str);
大致看了下说明意思。
(?s) 开启单行模式 DOTALL 让. 号匹配任意字符
(.) 任意字符 并捕获在第一组
(?=.*\1) 这是断言, 表示后面内容将是 任意个字符加上第一组所捕获的内容
第一条:开启正则的某些模式,感觉跟我没多少关系,我这是要去除重复的字符串,他这是去字母。
从第二条看过去来看,关键应该是分组,大致是思路我有点印象了,还是说匹配某个字符串,然后添加了个断言,第三条就是那个断言,也就是说将当前字符串做一个分组,放到断言里去了之后,匹配重复的部分。然后我对着将我的需求修改了一下。
String reg = "(\\d{5},)(?=(\\d{5},)*\\1)";
具体代码如下
String str = "abcdeabcdeabcdeaaaaaadddddceeeeabcccccccacadaeec";
String str1 = "10110,10254,10554,11025,10254,11002,11532,10110,";
String reg = "(\\d{5},)(?=(\\d{5},)*\\1)";
str = str.replaceAll("(?s)(.)(?=.*\\1)", "");
str1 = str1.replaceAll(reg, "");
// str = str.replaceAll(reg, "");
System.out.println(str1);
一开始是断言里面没有加 * 导致匹配失败,我猜测如果不加的话将会只匹配一组了。
但是后来我发现这个里面有个限制,就是该字符串数组就会被我限制在5个里面,如果其中有某一条字符串超过了5位数,则会导致匹配失败,这可能是个不足,因为我现在在讲6个作为一组,然后一组一组的匹配的,所以才会有这个问题,如果是其他的话,应该就不会有这个问题了。
OK,暂时算是解决问题了。这个断言还是有点不好理解,感觉有点预言性质,但是又不是进入实际的匹配对象里面去,主要是用处大概是对当前是匹配对象做进一步的限制和条件,以增强匹配的正确性。这个可能需要做进一步的测试才能得知。先做到这了,断言还有很多用途(?<=exp)、(?=exp)、(?!exp)、(?