Java 中正则表达式的经典用法总结——捕获组
正则表达式常用功能:匹配、切割、替换、获取(从字符串中提取指定格式字符)
【String类下的正则的使用】
String 类中有几个常用的方法,会涉及到正则表达式。如下:
//根据正则表达式regex判断是否匹配,匹配为true 否则false
boolean matches(String regex)//将满足正则表达式的地方,替换为指定的字符replacement。
String replaceAll(String regex, String replacement)//将满足正则表达式的地方作为切分点,切分为字符数组
String[] split(String regex)
上面三个方法涉及到了匹配、切割、替换。String功能有限,所以有了正则表达式对象Pattern和Matcher,用来提供更加强大的功能。
【通过正则对象来使用】
步骤:
1. 将正则封装成对象Pattern p = Pattern.compile(regex);p.split(str)//切割
2. 通过正则对象获取匹配器对象 Matcher m = p.matcher(str)
3. 使用Matcher对象的方法对字符串进行操作//匹配判断 Attempts to match the entire region against the pattern.m.matches();//替换Replaces every subsequence of the input sequence that matches the pattern with the given replacement string.m.replaceAll(String replacement)//获取 Attempts to find the next subsequence of the input sequence that matches the pattern.m.find();
一般情况下,除了“获取”功能需求,其他基本使用String类的函数方法就可以了。
我们看一下具体的含义:
//匹配判断 Attempts to match the entire region against the pattern.
boolean m.matches();//替换Replaces every subsequence of the input sequence that matches the pattern with the given replacement string.
String m.replaceAll(String replacement)//获取 Attempts to find the next subsequence of the input sequence that matches the pattern.
boolean m.find();
匹配过程中遇到失败便会终止,直接返回fasle
切割,替换是对整个字符串操作,字符串中所有满足正则条件的地方都会进行相应操作。也就是一次调用,作用于整个字串。
获取就不一样了,每调用一次,判断是否有下一个匹配的子串,返回值是boolbean类型
所以一般是结合while
循环使用,先用 boolean m.find()
判断是否有下一个匹配的子串,再使用String m.group()
,来获取匹配的子串。
【正则表达式常用构造摘要】
1.字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
2. 预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
3. Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
4. 边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾
【正则中的捕获组】
正则式中可以使用( )
括号将多个元素封装成组,封装成的组可以看做是一个大元素
,这样就可以使用数量词进行处理。
[ATCG]+ //[ATCG]表示匹配ATCG四个中的任意一个,[ATCG]+表示0个或多个,也就是匹配只含有A、T、G、C的字串如ATGGCTAGCGATG(ATGC)+表示ATGC整体出现0次或多次 如ATGCATGCATGC....
在表达式 ((A)(B(C))) 中,存在四个这样的组:
1 ((A)(B(C)))
2 (A)
3 (B(C))
4 (C)
获取过程中可以通过传入m.group(int num)组号,获取相应组的匹配结果。
public class B {public static void main(String[] args) {String pattern = "((A)(B(C)))D";// 创建 Pattern 对象Pattern r = Pattern.compile(pattern);// 现在创建 matcher 对象Matcher m = r.matcher("ABCDEABCDF");while(m.find()) {System.out.println("group(0) : " + m.group(0));// 匹配结果System.out.println("group(1) : " + m.group(1));// 第一个括号((A)(B(C))所匹配的内容System.out.println("group(2) : " + m.group(2));// 第二个括号(A)所匹配的内容System.out.println("group(3) : " + m.group(3));// 第三个括号(B(C))所匹配的内容System.out.println("group(4) : " + m.group(4));// 第三个括号(C)所匹配的内容System.out.println("---------------");} }
输出结果如下
group(0) : ABCD
group(1) : ABC
group(2) : A
group(3) : BC
group(4) : C
---------------
group(0) : ABCD
group(1) : ABC
group(2) : A
group(3) : BC
group(4) : C
---------------
另外(Ax)\\1+(BM)\\2+
,\\1+
表示与第1组(Ax)相同的出现1次以上,与第二组(BM)相同的也出现1次以上
public static void main(String[] args) {String pattern = "(Ax)\\1+(BM)\\2+";//String pattern = "(Ax)(BM)\\1+\\2+";//这样无法匹配//String pattern = "(Ax)(BM)\\1+\\2{1,}";//这样也无法匹配// 创建 Pattern 对象Pattern r = Pattern.compile(pattern);// 现在创建 matcher 对象Matcher m = r.matcher("AxAxBMBMBMBM");while(m.find()) {System.out.println("group(0) : " + m.group(0));// 匹配结果System.out.println("group(1) : " + m.group(1));// 第一个括号(Ax)所匹配的内容System.out.println("group(2) : " + m.group(2));// 第二个括号(BM)所匹配的内容System.out.println("---------------");} }
输出结果
group(0) : AxAxBMBMBMBM
group(1) : Ax
group(2) : BM
---------------=
word文档中也可以使用这也通配符来进行高级替换,很实用的技巧
详细见另一篇博文WPS以及Office 下 word 文档,使用通配符进行高级替换
在使用split()时,可能会使用到$num,
如 str = str.replaceAll("(.)\\1+","$1");
$1表示前一个参数的第一组
public static void main(String[] args) {String pattern = "(.)\\1+(BB)\\2+";// 创建 Pattern 对象Pattern r = Pattern.compile(pattern);// 现在创建 matcher 对象Matcher m = r.matcher("...BBBBCC..BBBBCC");String res=m.replaceAll("$1$2");//替换为.BBSystem.out.println(res);}
输出结果
.BBCC.BBCC
【例子1】
/*我我...我我...我我我我...要要要要...要要要要...
学学学学学...学学编编...编编编编..编..编...程程
...程程程——>我要学编程*/public class RegexTest{public static void main(String[] args){test();}/** 1. 治疗口吃:我我...我我...我我我我...要要要要...要要要要...学学学学学...学学编编...编编编编..编..编...程程...程程程*//** 1. 治口吃*/public static void test(){String str = "我我...我我...我我我我...要要要要...要要要要...学学学学学...学学编编...编编编编..编..编...程程...程程程";//1. 将字符串中.去掉,用替换。str = str.replaceAll("\\.+","");//2. 替换叠词str = str.replaceAll("(.)\\1+","$1");System.out.println(str);}}
【例子2】
import java.util.TreeSet;
import java.io.PrintStream;public class RegexTest
{public static void main(String[] args){test();}/** ip地址排序。* 192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55*/public static void test(){String ip_str = "192.168.10.34 127.0.0.1 3.3.3.3 105.70.11.55";//1. 为了让ip可以按照字符串顺序比较,只要让ip的每一段的位数相同。//所以,补零,按照每一位所需最多0进行补充,每一段都加两个0。ip_str = ip_str.replaceAll("(\\d+)","00$1");System.out.println(ip_str);//然后每一段保留数字3位。ip_str = ip_str.replaceAll("0*(\\d{3})","$1");System.out.println(ip_str);//1. 将ip地址切出。String[] ips = ip_str.split(" +");TreeSet<String> ts = new TreeSet<String>();for(String ip : ips){ts.add(ip);}for(String ip : ts){System.out.println(ip.replaceAll("0*(\\d+)","$1"));}}
}
正则之环视
附上牛客练习题一道
https://www.nowcoder.com/questionTerminal/758401c48ddc4deebb955821e175614d
Java中用正则表达式截取字符串中第一个出现的英文左括号之前的字符串。比如:北京市(海淀区)(朝阳区)(西城区),截取结果为:北京市。正则表达式为( A )
A “.*?(?=\()”
B “.*?(?=()”
C “.*(?=\()”
D “.*(?=()”
本题涉及到正则贪婪和非贪婪匹配以及环视
关于贪婪和非贪婪匹配见 正则表达式贪婪与非贪婪模式
关于正则环视分析见 深入理解正则表达式环视的概念与用法
Java 中正则表达式的经典用法总结——捕获组相关推荐
- Java中split函数的用法及使用示例
Java中split函数的用法及使用示例 2010-05-04 10:21 日志原文:http://lhgc.blog.sohu.com/80444801.html java.lang.string. ...
- 1000行代码徒手写正则表达式引擎【1】--JAVA中正则表达式的使用
简介: 本文是系列博客的第一篇,主要讲解和分析正则表达式规则以及JAVA中原生正则表达式引擎的使用.在后续的文章中会涉及基于NFA的正则表达式引擎内部的工作原理,并在此基础上用1000行左右的JAVA ...
- JAVA中split函数的用法
JAVA中split函数的用法 只写经常使用的,并不完整. 1.基本用法,将字符串按照指定字符串进行分割,例如: public class Main {public static void main( ...
- php session举例,PHP 中session的经典用法
PHP中session的经典用法 PHP中的session默认情况下是使用客户端的Cookie.当客户端的Cookie被禁用时,会自动通过Query_String来传递. Php处理session会话 ...
- Java中Date各种相关用法
Java中Date各种相关用法 本文主要介绍Java中Date各种相关用法. AD: Java中Date各种相关用法(一) 1.计算某一月份的最大天数 Java代码 Calendar time=C ...
- java中arraycopy的用法_[jdk源码阅读系列]Java中System.arraycopy()的用法
本文转载,原文链接: 3分钟了解Java中System.arraycopy的用法 - 伊万夫斯基 - 博客园 https://www.cnblogs.com/benjieqiang/p/114288 ...
- JAVA中 BufferedImage、ImageIO用法
转载:JAVA中BufferedImage.ImageIO用法 - 邓维-java - 博客园 (cnblogs.com) BufferedImage BufferedImage是其 ...
- Java中正则表达式的使用
JAVA中正则表达式的使用 如果出现连续相同的要分割的字符,那么会出现空字符串 1.split方法 2.pattern类编译正则3.matches类匹配正则 public class RegexTes ...
- java中compare语句的用法,compare的用法_java中 compareTo()的程序代码及用法
compare的用法与区别? 一.用法 v. (动词) 1.compare的基本意思是"比较,对照",主要用于比较事物的典型特征及其价值,而不在于比较相同与不同. 2.compar ...
最新文章
- 高阶程序员之路-轻松学习分布式锁
- PHP项目学习——控件
- 多维多重背包问题_满满干货!背包问题全总结(带c++源码)
- day14 集合与函数
- Visual Studio Code 使用教程
- 静默安装oracle11.2.0.4
- MongoDB常用使用场景介绍
- 南京航空航天大学2020数据结构课设
- python并发处理机制_Python并发编程—同步互斥
- JavaScript——Object类型
- 如何安装无签名认证的rpm包
- mysql并发参数查看_MySQL Innodb 并发涉及参数
- debian添加快捷启动方式
- php如何输出换行,PHP怎样才能让输出的内容自动换行
- 聊聊编码那些事——Unicode,gb2312,cp936,GBK,GB18030
- 爬虫-3-requests和代理
- python网格交易法详解_期货交易技巧:等分网格交易法详解
- libusb,libusbk,winusb的区别
- Ubuntu与arm开发板之间构建NFS数据通道
- 日志查看 docker容器启动失败原因