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

乍一看,需求貌视很简单啊,直接上 非贪婪模式的 双向零宽断言(有的资料上也叫 预搜索、预查、环视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<String> matches(String src,String reg){
Pattern pattern = Pattern.compile(reg);
Matcher matcher = pattern.matcher(src);
List<String> 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<String> 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<String> 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
}
}
}

  

收功~

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. 黑马程序员_毕向东_Java基础视频教程——变量(随笔)

    变量 变量 就是将不确定的数据进行存储.也就是需要在内存中开辟一块空间. 内存就是一块运算区域.内存越大.内存中装的数位就越多.运算就越快 ============================== ...

  2. centos6下filebeat多开问题

    centos6下filebeat多开问题 0. 场景 比如之前在用filebeat做收集,但是想新开一个实例把之前的日志全部重新导一遍,如果直接指定filebeat -c 是不行的,因为filebea ...

  3. Template模式C++实现

    #include <iostream> using namespace std; class AbstractClass { public: void TemplateMethod() { ...

  4. HTML标签和属性三

    八.列表 1.列表的作用 让数据有条理的显示,在数据之前添加标识 但是现在页面布局,经常会使用到无序列表 2.列表的组成 ①有序列表 <ol> <li></li> ...

  5. Django认证系统之自带auth_user表操作

    Django自带auth_user表操作: views.py from django.contrib  import  auth#引入auth模块 from django.contrib.auth.m ...

  6. Kubectl exec 的工作原理解读

    对于经常和 Kubernetes 打交道的 YAML 工程师来说,最常用的命令就是 kubectl exec 了,通过它可以直接在容器内执行命令来调试应用程序.如果你不满足于只是用用而已,想了解 ku ...

  7. [SD心灵鸡汤]006.每月一则 - 2015.10

    1. 贫不足羞,可羞是贫而无志. 2. 艺术的大道上荆棘丛生,这也是好事,常人望而却步,只有意志坚强的人例外. 3. 古今中外,凡成就事业,对人类有作为的无一不是脚踏实地.艰苦攀登的结果. 4. 理想 ...

  8. [Objective-C] 017_UI篇_UIView(中)

    在上篇我们简单讲了UIView的坐标与几何结构,这篇我们来实战UIView一下.UIView在App中有着绝对重要的地位,因为可视化控件几乎都是UIView的子类.在App负责渲染区域的内容,并且响应 ...

  9. Spring_使用JdbcTemplate和JdbcDaoSupport

    1.JdbcTemplate 简化 JDBC 模板查询 ①每次使用都创建一个 JdbcTemplate 的新实例, 这种做法效率很低下.②JdbcTemplate 类被设计成为线程安全的, 所以可以再 ...

  10. 记一次使用windbg排查内存泄漏的过程

    一.背景 近期有一个项目在运行当中出现一些问题,程序顺利启动,但是观察一阵子后发现内存使用总量在很缓慢地升高, 虽然偶尔还会往下降一些,但是总体还是不断上升:内存运行6个小时候从33M上升到80M: ...