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

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

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

  1. String test = "C77de3a4Cfg56C78ha123C923aabC123";
  2. String reg = "((?<=C\\d{1,10}+))(.+?)((?=(C\\d+)+))";
  3. Pattern pattern = Pattern.compile(reg);//这里因为反向零宽断言不能出现不固定长度,所以把C\d+处理成了C\d{1,10},见https://www.jb51.net/article/73404.htm
  4. Matcher matcher = pattern.matcher(test);
  5. while (matcher.find()){
  6. System.out.print(matcher.group()+" ");//de3a4Cfg56 ha123 aab
  7. }

  

  1. 再处理下首尾遇到非C\d+的 串,表达式变成:
  1. String reg = "((?<=C\\d{1,10}+)|^)(.+?)((?=(C\\d+)+)|$)";

  

  1. 这里,发现了 不能 处理连续C\d+这 种情况,想了很久,最后只能一个很不爽的实现来搞定了:
  1. String test = "aC77de3a4Cfg56C78C66ha123C923aabC123g";
  2. String reg = "((?<=C\\d{1,10}+)|^)(.+?)((?=(C\\d+)+)|$)";
  3. test = test.replaceAll("("+"C\\d+"+")("+"C\\d+"+")+","$1");//预先将连续的可匹配串替换掉
  4. Pattern pattern = Pattern.compile(reg);//因为
  5. Matcher matcher = pattern.matcher(test);
  6. while (matcher.find()){
  7. System.out.print(matcher.group()+" ");//a de3a4Cfg56 ha123 aab g
  8. }

 

  1. 结果,连续C\d+打头 这种情况还得单独做处理:
  1. String test = "C66C77de3a4Cfg56C78C66ha123C923aabC123g";
  2. String reg = "((?<=C\\d{1,10}+)|^)(.+?)((?=(C\\d+)+)|$)";
  3. test = test.replaceAll("^(C\\d+)+","");//预先将打头连续的可匹配串替换成空
  4. test = test.replaceAll("("+"C\\d+"+")("+"C\\d+"+")+","$1");//预先将串中连续的可匹配串替换掉
  5. Pattern pattern = Pattern.compile(reg);
  6. Matcher matcher = pattern.matcher(test);
  7. while (matcher.find()){
  8. System.out.print(matcher.group()+" ");//de3a4Cfg56 ha123 aab g
  9. }

 

  1. 终于大功告成~,最后把上面的逻辑封装成两个工具方法,第一个直接返回匹配串的List,第二个返回匹配 指定内容以外的 内容的List
  1. import java.util.ArrayList;
  2. import java.util.List;
  3. import java.util.regex.Matcher;
  4. import java.util.regex.Pattern;
  5.  
  6. public class RegUtil {
  7. public static List<String> matches(String src,String reg){
  8. Pattern pattern = Pattern.compile(reg);
  9. Matcher matcher = pattern.matcher(src);
  10. List<String> list = new ArrayList<>();
  11. while (matcher.find()){
  12. list.add(matcher.group());
  13. }
  14. return list;
  15. }
  16.  
  17. /**
  18. * 注意,simpleReg正则必须为不带分组的简单正则表达式,至多一个限定符,且只能是+,限定符匹配串串长不超过10字符,例如:C\d+ d+长度不超过10(正), C\d* (误)
  19. * 否则匹配时可能报错
  20. * 匹配 src中匹配了simpleReg以外 的内容
  21. * @param src
  22. * @param simpleReg
  23. * @return
  24. */
  25. public static List<String> beyondMatches(String src,String simpleReg){
  26. int index = simpleReg.indexOf("+");
  27. String preMatch = index!=-1?new StringBuilder(simpleReg).insert(index,"{1,10}").toString():simpleReg;
  28. return matches(src.replaceAll("^("+simpleReg+")+","").replaceAll("("+simpleReg+")("+simpleReg+")+","$1")
  29. ,"((?<="+preMatch+")|^)(.+?)((?=("+simpleReg+")+)|$)");
  30. }
  31.  
  32. public static void main(String[] args) {
  33. String test = "C2C12C21caaCbC12C66C77de3a4Cfg56C78ha123C923aabC123C321";
  34. List<String> result =RegUtil.matches(test,"C\\d+");
  35. for(String m:result){
  36. System.out.print(m+" ");//C2 C12 C21 C12 C66 C77 C78 C923 C123 C321
  37. }
  38. System.out.println();
  39. System.out.println("========");
  40. result =RegUtil.beyondMatches(test,"C\\d+");
  41. for(String m:result){
  42. System.out.print(m+" ");//caaCb de3a4Cfg56 ha123 aab
  43. }
  44. }
  45. }

  

  1. 收功~

java正则匹配 指定内容以外的 内容的更多相关文章

  1. java 正则匹配空格字符串 正则表达式截取字符串

    java 正则匹配空格字符串 正则表达式截取字符串 需求:从一堆sql中取出某些特定字符串: 比如配置的sql语句为:"company_code = @cc and project_id = ...

  2. 通用且常用的Java正则匹配工具,用以检查邮箱名、电话号码、用户密码、邮政编码等合法性

    一个通用且常用的Java正则匹配工具,用以检查邮箱名.电话号码.用户密码.邮政编码等合法性. import java.util.regex.Matcher; import java.util.rege ...

  3. 关于JAVA正则匹配空白字符的问题

    今天遇到一个字符串,怎么匹配空格都不成功!!! 我把空格复制到test.properties文件 显示“\u3000” ,这是什么? 这是全角空格!!! 查了一下    \s    不支持全角 1.& ...

  4. java正则匹配

    java正则提取需要用到Matcher类,下面给出案例示例供参考 需要提取车牌号中最后一个数字,比如说:苏A7865提取5,苏A876X提取6import java.util.regex.Matche ...

  5. 关于JAVA正则匹配空白字符的问题(全角空格与半角空格)

    今天遇到一个字符串,怎么匹配空格都不成功!!! 我把空格复制到test.properties文件 显示“\u3000” ,这是什么? 这是全角空格!!! 查了一下    \s    不支持全角 1.& ...

  6. java:正则匹配Pattern,Matcher

    一.正则匹配Pattern,Mather String s = "aa424fsfsd92lfjw2755097"; Pattern p = Pattern.compile(&qu ...

  7. java正则匹配${xxx} 排除单引号双引号内的内容,前提引号必须成对出现

    public static void main(String[] a) { String wpp = "select 1, ${mark} '``this is, `/message22` ...

  8. java正则匹配多个子字符串样例

    文本内容: 上海市黄浦区瑞典江苏省无锡市广东省深圳市南山区 我希望分别将字符串中的省份,城市名,城区名匹配出来,如匹配不出来就默认放在省份中. public static HashMap<Str ...

  9. java正则匹配正则表达式

    1.简单匹配小案例 public static void main( String[] args ){ // 按指定模式在字符串查找 String line = "This order wa ...

随机推荐

  1. python --内建结构 汉诺塔结构

    规则: 1.每次移动一个盘子 2.任何时候大盘子在下面,小盘子在上面 方法: 1.n=1:直接将A上的盘子移动到c 上面,A->C 2.n=2: 1>A->B 2>A-> ...

  2. PAT 1002 A+B for Polynomials (25分)

    题目 This time, you are supposed to find A+B where A and B are two polynomials. Input Specification: E ...

  3. appium——如何导出夜神模拟器下载“微信”app的apk

    背景:夜神模拟器是一款功能强大的安卓模拟器,但是当我们在上面下载APP应用后,通常不知道apk文件在哪里,下面以“微信”APP为例做一下详细介绍. 一般情况下,使用夜神安卓模拟器下载的文件只能在夜神安 ...

  4. 读懂这几个关键词,你就能了解 Docker 啦

    基于高度虚拟化所诞生的容器技术,如今已经走向大规模应用.那么容器.虚拟机.Docker.Openstack.Kubernetes 之间又有什么关系,对现在的选择有什么影响呢? 上世纪 60 年代,计算 ...

  5. Aangular 父子间组件传递

    1.父子间组件传递------重点&难点 Vue.js和Angular中的父子间消息传递原理一样,都可以用口诀: “Props Down,Events Up” 方向1:父 =>子 父组件 ...

  6. 5.1 Go函数定义

    1 Go函数定义 Go函数是指:一段具有独立功能的代码,然后可以在程序中其他地方多次调用. Go分为自定义函数,系统函数. 函数可以将一个大的工作拆解成小的任务. 函数对用户隐藏了细节. Golang ...

  7. Flask开发技巧之异常处理

    Flask开发技巧之异常处理 目录 Flask开发技巧之异常处理 1.Flask内置异常处理 2.HTTPException类分析 3.自定义异常处理类 4.方便的定义自己的错误类 5.注意事项 本人 ...

  8. 王艳 201771010127《面向对象程序设计(java)》第十三周学习总结

    一:理论部分. 1.事件处理基础. 1)事件源:能够产生事件的对象都可以成为事件源,如文本框.按钮等.一个事件源是一个能够注册监听器并向监听器发送事件对象的对象. 2)事件监听器:事件监听器对象接收事 ...

  9. Freemarker + iTextRender 实现根据模板网页生成PDF

    #0 背景 工作需要实现导出PDF的功能,在进行简单调研后,我决定采用Freemarker + iTextRender进行实现. 基本思路如下: Freemarker实现根据动态数据渲染出需要导出的H ...

  10. 第二篇-用Flutter手撸一个抖音国内版,看看有多炫

    前言 继上一篇使用Flutter开发的抖音国际版 后再次撸一个国内版抖音,大部分功能已完成,主要是Flutter开发APP速度很爽,  先看下图 项目主要结构介绍 这次主要的改动在api.dart 及 ...