博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java正则匹配 指定内容以外的 内容
阅读量:7044 次
发布时间:2019-06-28

本文共 3226 字,大约阅读时间需要 10 分钟。

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

乍一看,需求貌视很简单啊,直接上 非贪婪模式的 双向零宽断言(有的资料上也叫 预搜索、预查、环视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.htmMatcher 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 } }}

  

收功~

转载于:https://www.cnblogs.com/wzluo09/p/9505738.html

你可能感兴趣的文章
centos6.5 升级python2.66 to 2.78
查看>>
unity3d结合轮廓显示,实现完整的框选目标(附Demo代码)
查看>>
netstat
查看>>
Office 365 - SharePoint 2013 Online之添加App开发工具Napa
查看>>
升级R语言
查看>>
Android 百度地图 SDK v3.0.0 (四) 引入离线地图功能
查看>>
FancyBox - 经典的 jQuery Lightbox 插件
查看>>
sqoop:mysql和Hbase/Hive/Hdfs之间相互导入数据
查看>>
透视转换
查看>>
html的下拉框的几个基本使用方法
查看>>
超越Web,Javascript在物联网的应用
查看>>
云适配技术原理
查看>>
为iPhone 6设计自适应布局
查看>>
PHP操作数据库PDO
查看>>
Android colors.xml 颜色列表
查看>>
EF Code First 一对多、多对多关联,如何加载子集合?
查看>>
缓存篇~第六回 Microsoft.Practices.EnterpriseLibrary.Caching实现基于方法签名的数据集缓存...
查看>>
Android ROM 制作教程
查看>>
将一列包含多个ID拆分多行
查看>>
Ibatis入门基本语法(转) good
查看>>