今天群里有个人问,怎样用增则表达式匹配三角形的三边,其实只是要匹配三个数字而已,如 301 402 503 开始认为很简单,我就写了一个   "(([1-9]\\d?)\\s){2}$2" 结果他说错了,我感觉很奇怪,于是自己打开电脑试了试,果然是错的,然后看了看以前的笔记,发现我的Back 引用捕获组错了,因为$符号是在不同字符串中对捕获组的引用看下面这个方法

 public static void text_1(){String str="我。。我要。。。要要要。。学。。学。编。。。程";str=str.replaceAll("\\。+","");System.out.println(str);<span style="background-color: rgb(255, 255, 153);">str=str.replaceAll("(.)\\1*","$1");</span>System.out.println(str);}

这句话的意思是将$1调用(.)匹配到的结果,注意是匹配到的结果,也就是()括号里匹配到什么就被调用什么,这也是本人为什么要写这篇博客的原因所在。

可能大家还没有理解我的意思,下面跟着我来理解

上面说的$是在不同字符串中的引用捕获组,我一直强调的是引用的是结果,看下面这个代码:

 public void test(){<span style="color:#3333ff;">String regex="(([1-9]\\d?)\\s){2}\2";</span>String str="3 4 5";System.out.println(str.matches(regex));}

上面这段代码是我一直想不懂最后的结果为什么是false, String regex="(([1-9]\\d?)\\s){2}\2";

我们来分析这句话:([1-9]\\d?)  这句的意思是匹配一个正整数,如3,401,等   。([1-9]\\d?)\\s这句话是匹配一个数之后空格隔开,(([1-9]\\d?)\\s){2}正好出现两次也就是如:3 4 ,最后\2是调用角标为2的捕获组,也就是([1-9]\\d?) ,自己一直在思考为什么是错的,知道看到一篇博文才恍然大悟,引用捕获组的不是捕获组里面的表达式,而是引用捕获组所捕获到的具体内容,拿上面的例子来说:当第一次匹配时,([1-9]\\d?) 此匹配组所捕获的是3这个具体的字符串,所以你下次引用时就必须为3这个字符串,而不是再次调用([1-9]\\d?) 这个正则表达式这么简单,这就是我以前最大的误区,所以,自己也是花了很多时间才发现,改正上面的代码:

public static void test(){<span style="color:#000099;">String regex="([1-9]\\d*\\s){2}[1-9]\\d*";</span>String str="304 4 5";System.out.println(str.matches(regex));}

归根结底是我将{n}出现次数和\n引用捕获组搞混淆了,希望大家不要记错了!!!下面是我为大家扒过来的我觉得比较好的博文,这里我只是强调捕获组引用的概念,其他关于正则表达式不做过多的介绍,(现在已经深夜1.30了,哎,苦逼的程序员人生啊,该睡了)看下面代码:

Regex :

  • 本文主要讲述正则表达式中的捕获组(Capturing Group)的概念
  • 本文的正则表达式在 Java 中测试(需要注意的是这里的部分正则表达式在 Java7 中才能应用,下面会注明)
  • 本文正则表达式用           高亮标出

Capturing Group : (X)

简单的理解就是把正则表达式中的某部分用 () 括起来表示为一个组,纯理论解释不怎么好解释,详细还看下面的举例。

举例:

  • (Ggi)cci 与Ggicci 都匹配 "Ggicci",只不过前面把 Ggi 作为一个捕获组,在匹配到的同时它可以捕获 "Ggi" 这样的字符串供逆向引用(Back Reference),见下一栏。
  • Ggicci* 与(Ggicci)* 不同在于Ggicci* 匹配的是 "Ggicci" 和 "Ggicci…i" 这种情况,而(Ggicci)* 匹配的是 "Ggicci" 和 "GgicciGgicci…Ggicci" 这种情况。

Back Reference :

逆向引用指的是正则表达式中某个捕获组捕获到的字符串供正则表达式构建其自身匹配规则的方式。这是我自己归纳的理论,听起来肯定很晦涩,详细见下面讲解

捕获组的编号与命名:

如 ((A)(B(C))) “摘自Java7 Doc”,这里有 4 个组:

  • 编号 捕获组
    1 ((A)(B(C)))
    2 (A)
    3 (B(C))
    4 (C)

在未对捕获组人为命名的时候,对捕获组的编号是默认的从左到右依次萃取 ( 和与之对应成一对的 )。如上,一共 4 个 ( ,所以有 4 个组,按 ( 的出现次序编号。

  • (?<name>X) 命名捕获组为 name,在 Java7 中;

       1: String source = "Ggicci was born in 1991 and is 20 years old now. He weights 54kg and is 170cm tall.";        
       2: Pattern pattern = Pattern.compile("(?<user>[Gg]gicci)|(?<digital>\\d+)");        
       3: Matcher matcher = pattern.matcher(source);
       4: while (matcher.find()) {
       5:     System.out.println(matcher.group());
       6: }

    代码中的正则表达式(已加粗)匹配 Ggicci 或 ggicci 或一段数字,输出为:
       1: //输出:
       2: Ggicci
       3: 1991
       4: 20
       5: 54
       6: 170

    (?<user>[Gg]gicci) 把捕获组命名为 user,我们用 Matcher 类的 group(String name) 方法,即 matcher.group("user"); 可以获取该捕获组捕获的内容,其它的捕获组内容将为 null:
       1: System.out.println(matcher.group("user")); //替换上面 while 循环中的输出语句
       2: //输出:
       3: Ggicci
       4: null
       5: null
       6: null
       7: null

    当然用 Matcher 类的 group(int group) 方法也可以,这里 user 捕获组的默认编号为 1,所以 matcher.group(1) 同 matcher.group("user") 一样。(?<digital>\d+) 也同样去理解。
  • (?:X) 取消捕获组命名,注意这种方式连捕获组默认的编号也会取消,所以在调用 Matcher.group(int) 或 Matcher.group(String) 的时候会异常;
  • \n 表示引用第 n 个捕获组捕获到的内容;
       1: String source = "Hello, my my name is uh.. is is Gg.. ggicci ggicci ggicci ggicci";
       2: Pattern pattern = Pattern.compile("\\b(\\w+)\\b((\\s+)\\1\\b)+");
       3: Matcher matcher = pattern.matcher(source);
       4: while (matcher.find()) {
       5:     System.out.println(matcher.group());
       6: }

    这段正则表达式 \b(\w)\b((\s+)\1)+ 匹配字符串重复的以空格符间隔的单词。其中 \1 引用了捕获组 (\w) 匹配到的内容。比如 (\w) 第一次匹配了 "Hello",\1 引用了 "Hello" 后正则表达式其实已经变成了\bHello\b((\s+)Hello)+ 了(这是从形式上去理解,具体内部机制如何,亲,我目前真的不知道 : )),但是显然后面没有 "Hello" 可以匹配了,(\w) 第二次匹配了 "my",\1 引用了 "my",找到匹配,然后依次下去,输出如下:
       1: //输出:
       2: my my
       3: is is
       4: ggicci ggicci ggicci ggicci

  • \k<name> 表示引用命名为 name 的捕获组捕获到的内容,在Java7 中;
       1: //这里同上面的正则表达式一样,只不过给 \1 取了个名字叫 repeat
       2: //然后用 \k<repeat> 代替 \1 而已
       3: Pattern pattern = Pattern.compile("\\b(?<repeat>\\w+)\\b((\\s+)\\k<repeat>\\b)+");

java中的正则表达式捕获组与引用的概念相关推荐

  1. Java中的正则表达式 - Java Regex示例

    Java中的正则表达式 - Java Regex示例 欢迎使用Java中的正则表达式.它在Java中也称为Regex.当我开始编程时,java正则表达式对我来说是一场噩梦.本教程旨在帮助您掌握Java ...

  2. java 正则 捕获_Java通过正则表达式捕获组中的文本

    1.简介 Java 正则表达式如何捕获组中的文本 ?--请看下文. 2.代码 /** * 版权所有 编程十万个怎么办(www.tah1986.com) */ public class Capturin ...

  3. 正则表达式中的非捕获组是什么?

    非捕获组(即(?:) )如何在正则表达式中使用,它们有什么用? #1楼 在复杂的正则表达式中,您可能会希望使用大量的组,其中一些用于重复匹配,而另一些则提供反向引用. 默认情况下,与每个组匹配的文本会 ...

  4. java 中的正则表达式_Java中的正则表达式–软介绍

    java 中的正则表达式 正则表达式是一种可以应用于文本(Java中的String)的模式. Java提供了java.util.regex包,用于与正则表达式进行模式匹配. Java正则表达式与Per ...

  5. 详解Java中的正则表达式

    详解Java中的正则表达式,并列出常用的正则表达式语法和一些常用的场景. 判断一个字符串是否是由数字组成: 当不使用正则表达式的时候的实现代码: public class RegexDemo01 {p ...

  6. js 中的正则捕获组

    1.1 什么是捕获组 捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用.当然,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部. 捕获组有两种 ...

  7. 【JavaSE】java中的正则表达式(从0到1学会正则表达式)

    文章目录 前言 一.正则表达式的三个常用类 1.Pattern类 2.Matcher类 3.PatternSyntaxException类 二.正则表达式的底层实现 1.Matcher.find()和 ...

  8. java 正则表达式 判断 日期_怎么在java中利用正则表达式对时间日期进行判断

    怎么在java中利用正则表达式对时间日期进行判断 发布时间:2020-12-08 16:18:34 来源:亿速云 阅读:105 作者:Leah 这篇文章给大家介绍怎么在java中利用正则表达式对时间日 ...

  9. java正则表达式性能_译:Java 中的正则表达式性能概述

    译者:Darren Luo 1. 概述 在本快速教程中,我们将展示模式匹配引擎是如何工作的.我们还将介绍在 Java 中优化正则表达式的不同方式. 有关正则表达式的的使用介绍,请参阅此文. 2. 模式 ...

最新文章

  1. Android Eclipse JNI 调用 .so文件加载问题
  2. 94. Binary Tree Inorder Traversal二叉树的中序遍历
  3. Java程序员从笨鸟到菜鸟之(五)java开发常用类(包装,数字处理集合等)(下)
  4. unity透明通道加颜色_Unity-雪地效果的实现
  5. 数据库-MySQL-数据库设计-外键
  6. mysql怎么拿到一个表里的所有列名字
  7. Kubernetes集群安全:Api Server认证
  8. C++11基于范围的for循环
  9. jetbrains mono字体安装方法(LInux Windows MacOS系统)
  10. 铲雪车(snow)[欧拉回路]
  11. wo-27s管理员账户和密码_开机密码忘了怎么解决
  12. 移动研发平台EMAS 3.0全新升级,欢迎登陆阿里云官网搜索EMAS进行体验
  13. 归一化互相关(NCC)及其部分应用场景
  14. 思科和思杰联袂提供全面的桌面虚拟化解决方案
  15. C语言位操作--判断整数的符号
  16. 《速度与激情9》中有哪些槽点?
  17. codeforces 855-B. Marvolo Gaunt's Ring(背包问题)
  18. Python计算机视觉之全景图像拼接
  19. app android 升级提示,app版本升级原生弹框和进度提示(包含wgt升级)
  20. C# 基于免费人脸识别SDK完成人脸识别和注册

热门文章

  1. php编写开机启动脚本,设置 msyql php-fpm 开机自动启动脚本
  2. lua和unity如何交互_Unity中C#对象与Lua之间交互的原理
  3. Vue-第七天 学习与相关问题总结
  4. 申请补办 CET(纸笔考试)成绩证明的方法
  5. 博士申请 | 澳大利亚悉尼科技大学招收人工智能/软件工程方向全奖博士生
  6. NeurIPS 2021 | PCAN:高效时序建模,提升多目标追踪与分割性能
  7. 推荐几个出论文的好方向
  8. acm第二节2020.4.2-4.4补
  9. SpringBoot AOP实现接口次数访问统计
  10. AI识虫:林业病虫害数据集和数据预处理方法