java匹配出某单词除外_java正则匹配 指定内容以外的 内容

这篇博客讲述了如何使用Java正则表达式匹配出指定内容以外的数据,特别是在处理非连续和连续特定模式字符串时的方法,包括零宽断言和预查的使用,以及最后封装成的两个工具方法。
摘要由CSDN通过智能技术生成

今天,遇到一个需要 匹配出 指定内容以外的 内容的需求。

乍一看,需求貌视很简单啊,直接上 非贪婪模式的 双向零宽断言(有的资料上也叫 预搜索、预查、环视lookaround):

比如,我要匹配 串内所有 大写C打头后接数字(C\d+) 以外的 匹配数据,也就是:非贪婪匹配C\d+和后一个C\d+之间的内容

String test = "C77de3a4Cfg56C78ha123C923aabC123";

String reg = "((?<=C\\d{1,10}+))(.+?)((?=(C\\d+)+))";

Pattern pattern = Pattern.compile(reg);//这里因为反向零宽断言不能出现不固定长度,所以把C\d+处理成了C\d{1,10},见https://www.jb51.net/article/73404.htm

Matcher matcher = pattern.matcher(test);

while (matcher.find()){

System.out.print(matcher.group()+" ");//de3a4Cfg56 ha123 aab

}

再处理下首尾遇到非C\d+的 串,表达式变成:

String reg = "((?<=C\\d{1,10}+)|^)(.+?)((?=(C\\d+)+)|$)";

这里,发现了 不能 处理连续C\d+这 种情况,想了很久,最后只能一个很不爽的实现来搞定了:

String test = "aC77de3a4Cfg56C78C66ha123C923aabC123g";

String reg = "((?<=C\\d{1,10}+)|^)(.+?)((?=(C\\d+)+)|$)";

test = test.replaceAll("("+"C\\d+"+")("+"C\\d+"+")+","$1");//预先将连续的可匹配串替换掉

Pattern pattern = Pattern.compile(reg);//因为

Matcher matcher = pattern.matcher(test);

while (matcher.find()){

System.out.print(matcher.group()+" ");//a de3a4Cfg56 ha123 aab g

}

结果,连续C\d+打头 这种情况还得单独做处理:

String test = "C66C77de3a4Cfg56C78C66ha123C923aabC123g";

String reg = "((?<=C\\d{1,10}+)|^)(.+?)((?=(C\\d+)+)|$)";

test = test.replaceAll("^(C\\d+)+","");//预先将打头连续的可匹配串替换成空

test = test.replaceAll("("+"C\\d+"+")("+"C\\d+"+")+","$1");//预先将串中连续的可匹配串替换掉

Pattern pattern = Pattern.compile(reg);

Matcher matcher = pattern.matcher(test);

while (matcher.find()){

System.out.print(matcher.group()+" ");//de3a4Cfg56 ha123 aab g

}

终于大功告成~,最后把上面的逻辑封装成两个工具方法,第一个直接返回匹配串的List,第二个返回匹配 指定内容以外的 内容的List:

import java.util.ArrayList;

import java.util.List;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class RegUtil {

public static List matches(String src,String reg){

Pattern pattern = Pattern.compile(reg);

Matcher matcher = pattern.matcher(src);

List list = new ArrayList<>();

while (matcher.find()){

list.add(matcher.group());

}

return list;

}

/**

* 注意,simpleReg正则必须为不带分组的简单正则表达式,至多一个限定符,且只能是+,限定符匹配串串长不超过10字符,例如:C\d+ d+长度不超过10(正), C\d* (误)

* 否则匹配时可能报错

* 匹配 src中匹配了simpleReg以外 的内容

* @param src

* @param simpleReg

* @return

*/

public static List beyondMatches(String src,String simpleReg){

int index = simpleReg.indexOf("+");

String preMatch = index!=-1?new StringBuilder(simpleReg).insert(index,"{1,10}").toString():simpleReg;

return matches(src.replaceAll("^("+simpleReg+")+","").replaceAll("("+simpleReg+")("+simpleReg+")+","$1")

,"((?<="+preMatch+")|^)(.+?)((?=("+simpleReg+")+)|$)");

}

public static void main(String[] args) {

String test = "C2C12C21caaCbC12C66C77de3a4Cfg56C78ha123C923aabC123C321";

List result =RegUtil.matches(test,"C\\d+");

for(String m:result){

System.out.print(m+" ");//C2 C12 C21 C12 C66 C77 C78 C923 C123 C321

}

System.out.println();

System.out.println("========");

result =RegUtil.beyondMatches(test,"C\\d+");

for(String m:result){

System.out.print(m+" ");//caaCb de3a4Cfg56 ha123 aab

}

}

}

收功~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值