我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Java正则表达式中如何实现分组和替换

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Java正则表达式中如何实现分组和替换

小编给大家分享一下Java正则表达式中如何实现分组和替换,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

    正则表达式的子表达式(分组)不是很好懂,但却是很强大的文本处理工具。

    1 正则表达式热身

    匹配电话号码

    // 电话号码匹配// 手机号段只有 13xxx 15xxx 18xxxx 17xxxSystem.out.println("18304072984".matches("1[3578]\\d{9}"));   // true// 座机号:010-65784236,0316-3312617,022-12465647,03123312336String regex = "0\\d{2}-?\\d{8}|0\\d{3}-?\\d{7}";String telStr = "010-43367458";System.out.println(telStr.matches(regex));  // true

    匹配邮箱

    String mail = "i@jiaobuchong.com.cn";String reg = "[a-zA-Z_0-9]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+){1,2}";System.out.println(mail.matches(reg));  // true

    特殊字符替换

    将不是中文的字符替换为空:

    String input = "神探狄仁&*%$杰之四大天王@bdfbdbdfdgds23532";String reg = "[^\\u4e00-\\u9fa5]";input = input.replaceAll(reg, "");System.out.println(input);   // 神探狄仁杰之四大天王

    汉字的Unicode编码范围是:\u4e00-\u9fa5

    2 分组

    组是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号为 0 表示整个表达式,组号 1 表示第一对括号扩起的组,以此类推。

    看 Java API 中 Pattern 中的描述:

    Capturing groups are numbered by counting their opening parentheses from left to right. In the expression ((A)(B(C))), for example, there are four such groups:

    ((A)(B(C)))
    2. (A)
    3. (B(C))
    4. (C)

    再比如 A(B(C))D 有三个组:组 0 是 ABCD,组 1 是 BC,组 2 是 C,

    可以根据有多少个左括号来来确定有多少个分组,括号里的表达式都称子表达式。

    Eg1:

    Matcher 对象提供很多方法:

    • goupCount() 返回该正则表达式模式中的分组数目,对应于「左括号」的数目

    • group(int i) 返回对应组的匹配字符,没有匹配到则返回 null

    • start(int group) 返回对应组的匹配字符的起始索引

    • end(int group) 返回对应组的匹配字符的最后一个字符索引加一的值

    // 这个正则表达式有两个组,// group(0) 是 \\$\\{([^{}]+?)\\}// group(1) 是 ([^{}]+?)String regex = "\\$\\{([^{}]+?)\\}";Pattern pattern = Pattern.compile(regex);String input = "${name}-babalala-${age}-${address}";Matcher matcher = pattern.matcher(input);System.out.println(matcher.groupCount());// find() 像迭代器那样向前遍历输入字符串while (matcher.find()) {    System.out.println(matcher.group(0) + ", pos: "            + matcher.start() + "-" + (matcher.end() - 1));    System.out.println(matcher.group(1) + ", pos: " +            matcher.start(1) + "-" + (matcher.end(1) - 1));}

    输出:

    1
    ${name}, pos: 0-6
    name, pos: 2-5
    ${age}, pos: 17-22
    age, pos: 19-21
    ${address}, pos: 24-33
    address, pos: 26-32

    group翻译成中文就是分组。

    group()或group(0)对应于整个正则表达式每次匹配到的内容,

    group(1)表示括号中(一个子表达式分组)匹配到的内容。

    Eg2:

    为了更直观的看分组,在 Eg1 的正则表达式上再多加一对括号:

    String regex = "(\\$\\{([^{}]+?)\\})";Pattern pattern = Pattern.compile(regex);String input = "${name}-babalala-${age}-${address}";Matcher matcher = pattern.matcher(input);// matcher.find() 方法会对 input 这个字符串多次进行匹配,如果能匹配到,这个匹配结果里就会包含多个分组,我们可以从分组里提取我们想要的结果while (matcher.find()) {    System.out.println(matcher.group(0) + ", pos: " + matcher.start());    System.out.println(matcher.group(1) + ", pos: " + matcher.start(1));    System.out.println(matcher.group(2) + ", pos: " + matcher.start(2));}

    输出:

    ${name}, pos: 0
    ${name}, pos: 0
    name, pos: 2
    ${age}, pos: 17
    ${age}, pos: 17
    age, pos: 19
    ${address}, pos: 24
    ${address}, pos: 24
    address, pos: 26

    由此可得出一对括号一个分组,可以通过左括号数来确定有多少个分组。

    通过group()获取分组中的匹配字串应用场景很广泛,

    在笔者的一个项目中,通过使用这个特性实现了很有意思的通配符替换,感动!

    Eg3(通过分组提取想要的数据):

    // 这个正则表达式会提取字符串中的「数字」和「字母」        Pattern pattern = Pattern.compile("([0-9]+).*?([a-zA-Z]+)");        String input = "那就20200719这样吧sunny。。。。。。。122432该拿什么与眼泪抗衡twinkle";        Matcher matcher = pattern.matcher(input);        // 每个匹配到的子串分组的个数        int group = matcher.groupCount();        // 如果输入串有多个可被匹配的子串,这里会多次进行匹配        while (matcher.find()) {            System.out.println("匹配到的子串:" + matcher.group());  // 匹配到的子串            for (int i = 1; i <= group; i++) {                System.out.println("分组" + i + ": " + matcher.group(i));            }        }

    输出:

    匹配到的子串:20200719这样吧sunny
    分组1: 20200719
    分组2: sunny
    匹配到的子串:122432该拿什么与眼泪抗衡twinkle
    分组1: 122432
    分组2: twinkle

    3 分组替换

    Eg1:

    String tel = "18304072984";// 括号表示组,被替换的部分$n表示第n组的内容tel = tel.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");System.out.print(tel);   // output: 183****2984

    replaceAll 是一个替换字符串的方法,正则表达式中括号表示一个分组,replaceAll 的参数 2 中可以使用 $n(n 为数字)来依次引用子表达式中匹配到的分组字串,"(\\d{3})\\d{4}(\\d{4})", "$1****$2",分为前(前三个数字)中间四个数字(最后四个数字) 替换为(第一组数字保持不变 $1)(中间为 * )(第二组数字保持不变 $2)。

    Eg2:

    String one = "hello girl hi hot".replaceFirst("(\\w+)\\s+(\\w+)", "$2 $1"); String two = "hello girl hi hot".replaceAll("(\\w+)\\s+(\\w+)", "$2 $1"); System.out.println(one);   // girl hello hi hotSystem.out.println(two);   // girl hello hot hi

    理解了Eg1,这个例子也自然就理解了。

    Eg3:

    来一个实用的例子,重复标点符号替换:

    String input = "假如生活欺骗了你,,,相信吧,,,快乐的日子将会来临!!!…………";// 重复标点符号替换String duplicateSymbolReg = "([。?!?!,]|\\.\\.\\.|……)+";input = input.replaceAll(duplicateSymbolReg, "$1");System.out.println(input);

    输出:

    假如生活欺骗了你,相信吧,快乐的日子将会来临!……

    正则表达式:([。?!?!,]|\\.\\.\\.|……)+,括号中是一个分组:表示一个标点符号,+表示这个分组出现一次或多次,$1分组的内容(一个标点符号)。replaceAll 就使用$1去对字符串进行替换了。

    Eg4:

    IP地址排序

    String ip = "192.68.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";ip = ip.replaceAll("(\\d+)", "00$1");System.out.println(ip);ip = ip.replaceAll("0*(\\d{3})", "$1");System.out.println(ip);String[] strs = ip.split(" ");Arrays.sort(strs);for (String str : strs) {    str = str.replaceAll("0*(\\d+)", "$1");    System.out.println(str);}

    输出:

    00192.0068.001.00254 00102.0049.0023.00013 0010.0010.0010.0010 002.002.002.002 008.00109.0090.0030
    192.068.001.254 102.049.023.013 010.010.010.010 002.002.002.002 008.109.090.030
    2.2.2.2
    8.109.90.30
    10.10.10.10
    102.49.23.13
    192.68.1.254

    • 让IP地址的每一段都是3位,替换之后有4位的情况

    • 保证IP地址每一段都是3位

    • 排序之

    写到这里,笔者不禁感叹,真的很强大!

    4 反向引用

    使用小括号指定一个子表达式分组后,匹配这个子表达式的文本可以在表达式或其它程序中作进一步的处理。默认情况下,每个分组会自动拥有一个组号,规则是:以分组的左括号为标志,从左向右,第一个分组的组号为1,第二个为2,以此类推。

    Eg:

    String regex = "(.)\\1(.)\\2";  System.out.println("安安静静".matches(regex));   // trueSystem.out.println("安静安静".matches(regex));   // false

    上面 (.) 表示一个分组,里面 . 表示任意字符,每一个字符都是一个分组,

    \\1表示组1(安)又出现了一次,\\2表示组2(静)又出现了一次。

    那匹配 安静安静,怎么写正则表达式?根据上面的例子,将安静分成一个组,然后这个组又出现了一次就是安静安静:

    String regex = "(..)\\1";  System.out.println("安静安静".matches(regex));   // trueSystem.out.println("安安静静".matches(regex));   // false

    5 反向引用替换

    Eg1:

    String str = "我我...我我...我要..要要...要要...找找找一个....女女女女...朋朋朋朋朋朋...友友友友友..友.友...友...友友!!!";        str = str.replaceAll("\\.+", "");System.out.println(str);str = str.replaceAll("(.)\\1+", "$1");System.out.println(str);

    输出:

    我我我我我要要要要要找找找一个女女女女朋朋朋朋朋朋友友友友友友友友友友!!!
    我要找一个女朋友!

    (.)表示任意一个字符都会成为一个分组;\\1+ 引用分组(一个字符),表示出现1次或多次这个分组。 $1引用分组(.)将多个重复字符替换成一个字符。

    Eg2:

    替换重复出现的两位数之间的内容:

    "xx12abdd12345".replaceAll("(\\d{2}).+?\\1", "");  //结果为 xx345

    是不是觉得很神奇!

    使用replace系列的方法要注意的一个异常: Java replaceAll()方法报错Illegal group reference

    看完了这篇文章,相信你对“Java正则表达式中如何实现分组和替换”有了一定的了解,如果想了解更多相关知识,欢迎关注编程网行业资讯频道,感谢各位的阅读!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Java正则表达式中如何实现分组和替换

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Java正则表达式中如何实现分组和替换

    小编给大家分享一下Java正则表达式中如何实现分组和替换,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!正则表达式的子表达式(分组)不是很好懂,但却是很强大的文本处理工具。1 正则表达式热身匹配电话号码// 电话号码匹配//
    2023-06-21

    python正则表达式如何实现分组

    这篇文章将为大家详细讲解有关python正则表达式如何实现分组,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。分组格式:(\w)注:在正则表达式中一对括号包围的内容表示分组,正则表达式中可以有多个分组用处:
    2023-06-26

    Java如何使用正则表达式实现替换文本功能

    本篇文章给大家分享的是有关Java如何使用正则表达式实现替换文本功能,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。具体如下:package replaceDemo;import
    2023-05-31

    php正则表达式如何替换指定部分

    这篇文章主要讲解了“php正则表达式如何替换指定部分”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“php正则表达式如何替换指定部分”吧!一、PHP正则表达式概述正则表达式是一种用于描述字符串
    2023-07-05

    Java 中的字符替换是否支持正则表达式?(Java字符替换支持正则表达式吗)

    在Java编程中,字符替换是一个常见的操作。而正则表达式则是一种强大的文本匹配工具,它可以用于搜索、替换和验证文本。那么,Java字符替换是否支持正则表达式呢?答案是肯定的。Java的String类提供了replaceAll
    Java 中的字符替换是否支持正则表达式?(Java字符替换支持正则表达式吗)
    Java2024-12-15

    Dreamweaver如何实现正则表达式字符查找替换

    这篇文章给大家分享的是有关Dreamweaver如何实现正则表达式字符查找替换的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1.打开“查找和替换”对话框 2.在“查找范围”选项中选择“文件夹”,然后选择要进行批量
    2023-06-08

    PHP中如何执行正则表达式的搜索和替换

    这篇文章主要介绍“PHP中如何执行正则表达式的搜索和替换”,在日常操作中,相信很多人在PHP中如何执行正则表达式的搜索和替换问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PHP中如何执行正则表达式的搜索和替换
    2023-06-25

    python正则表达式如何实现分组命名

    这篇文章主要介绍了python正则表达式如何实现分组命名,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。分组命名格式:(?P<名字>正则表达式)注:?P<名称>,英文书名号内是
    2023-06-26

    python正则表达式如何实现分组隐藏

    小编给大家分享一下python正则表达式如何实现分组隐藏,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!分组隐藏格式:(?:正则表达式)注:在括号内以?:开头的分组
    2023-06-26

    Java如何用多字节支持替换正则表达式

    Java中使用多字节支持替换正则表达式非常重要,可确保正则表达式模式与Unicode字符匹配。Pattern类和Matcher类可创建和使用正则表达式,Pattern.UNICODE_CHARACTER_CLASS标志启用多字节支持。Matcher.replaceFirst()和Matcher.replaceAll()方法可替换匹配项。通过这些方法,可以轻松实现多字节替换,对于处理包含各种语言和字符集的国际化数据非常有用。
    Java如何用多字节支持替换正则表达式
    2024-04-02

    如何使用DW正则表达式批量替换

    小编给大家分享一下如何使用DW正则表达式批量替换,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!想法:想把B

    怎么用Python正则表达式实现分页按钮href替换

    本篇内容介绍了“怎么用Python正则表达式实现分页按钮href替换”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!帖子上有分页功能的按钮,如
    2023-06-17

    php如何实现正则表达式匹配一段字符串替换

    这篇文章主要介绍了php如何实现正则表达式匹配一段字符串替换,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。php实现正则表达式匹配一段字符串替换的方法:1、创建一个PHP示例
    2023-06-21

    Python正则表达式如何进行字符串替换实例

    Python正则表达式在使用中会经常应用到字符串替换的代码。有很多人都不知道如何解决这个问题,下面的代码就告诉你其实这个问题无比的简单,希望你有所收获。 1.替换所有匹配的子串用newstring替换subject中所有与正则表达式rege
    2022-06-04

    java中如何使用正则表达式中的组

    这篇文章主要介绍java中如何使用正则表达式中的组,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!组是括号划分的正则表达式,可以根据组的编号来引用某个组。组号为0表示整个表达式,组号1表示从左到右被第一个括号扩起的组,
    2023-06-02

    如何在 Golang 中替换正则表达式匹配的文本?

    在 go 中,可使用 regexp.replaceall 函数替换符合正则表达式的文本,该函数需要三个参数:待替换字符串、匹配模式和替换文本。例如,将字符串中 "fox" 替换为 "dog":编译正则表达式模式 "fox"。使用 repla
    如何在 Golang 中替换正则表达式匹配的文本?
    2024-05-14

    Java利用正则表达式如何实现查找换行符

    这篇文章将为大家详细讲解有关Java利用正则表达式如何实现查找换行符,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。具体如下:默认情况下,正则表达式 ^ 和 $ 忽略行结束符,仅分别与整个输入
    2023-05-31

    PHP如何用多字节支持替换正则表达式

    本文介绍了如何利用PHP的mb_ereg_replace()和mb_ereg_replace_callback()函数,以多字节方式替换正则表达式,从而处理包含多字节字符的文本。mb_ereg_replace()函数实现多字节正则表达式替换,支持选项和回调函数的扩展功能。而mb_ereg_replace_callback()函数则允许开发者定义回调函数处理匹配内容。此外,本文强调了正确指定多字节字符集编码、测试正则表达式以及考虑使用更新的PHP正则表达式函数(如preg_match()和preg_repl
    PHP如何用多字节支持替换正则表达式
    2024-04-02

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录