1. 前言
正则表达式,又称规则表达式。正则表达式使用单个字符串来描述、进行一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式(规则)的文本。
2. 语法与元字符
正则表达式由普通字符(字母、数字以及部分特殊字符)以及元字符(具有特殊语义的字符)组成,下面给出一个示例:
下面会对一些经常使用的字符进行简单的介绍与示例演示,如果需要进行更详细深入的了解,可以通过此文档正则表达式-教程: https://www.runoob.com/regexp/regexp-tutorial.html 进行更加深入的了解。
2.1 基本限定符
2.2 选择匹配符
2.3 分组组合和反向引用符
2.4 字符匹配符
2.5 定位符
3. Java使用方法
JDK1.8关于正则表达式提供了一个官方工具包java.util.regex
,本文从满足基本使用的角度对其中一些类与方法做出一些简单介绍与解析,更加具体的内容可在jdk8在线api官方文档:https://www.matools.com/api/java8 中进行进一步了解。
3.1 使用方式
注意:正则表达式中的特殊字符(如.*+()$/\?[]^{}
)需要进行转义(即在前面加一条反斜杠”\“)才可进行使用。
而在java字符串中反斜杠"\"本身也需要进行转义才可以使用,所以在正则表达式中需要用到斜杠的地方,我们需要在前面再加一条斜杠来转义反斜杠。例如正则表达式\d
在java字符串应该写做“\\d”
下面以伪代码的形式进行简单演示使用流程:
//待匹配文本
String content = "helloWorld";
String ipContent = "127.0.0.1";
//1.创建一个Pattern对象(可以理解成就是一个正则表达式对象)
//匹配数字与英文字母
Pattern pattern = Pattern.compile("[a-zA-z]+");
Pattern pattern = Pattern.compile("[0-9]+");
Pattern pattern = Pattern.compile("([0-9]+)|([a-zA-z]+)");
//匹配ip地址,即数字.数字.数字.数字格式(d代表数字,+代表不限制位数,)
Pattern pattern = Pattern.compile("\\d+\\.\\d+\\.\\d+\\.\\d+");
//2.创建一个匹配器对象
//理解:matcher匹配器根据pattern正则表达式,到content文本中去匹配
Matcher matcher = pattern.matcher(content);
//3.开始循环匹配
while(matcher.find()) {
System.out.println("匹配字符:" + matcher.group(0))
}
3.2 Pattern类
Pattern对象是一个正则表达式对象,该类使用public static Pattern compile(String regex)方法传入正则表达式字符串进行构造。
3.2.1 Pattern.matches()
从源码可以看出本质上matches方法也是创建了Pattern对象并生成了Matcher匹配器,此方法一般可以用在快速验证文本是否符合格式的场景下。
3.3 Matcher类
Matcher是对输入的文本进行匹配的匹配器,该类使用Pattern类的public Matcher matcher(CharSequence input)方法传入CharSequence参数(例如String类型对象)进行构造。
3.3.1 Matcher.find()
public boolean find()方法解析说明:
-
现存在一个字符串String content = "1234, 5678, 9012";
-
假设指定一个正则表达式 Pattern.compile("\\d\\d\\d\\d");
-
运行find()函数之后,根据正则表达式,定位到第一个符合条件的子字符串
"1234"
后对matcher对象的属性int[] groups
进行赋值。groups[0] = 0记录子字符串开始的索引, group[1] = 4记录子字符串结束的索引+1。group[0]和group[1]意为子字符串在总字符串content的位置为[0, 4) -
同时记录Matcher对象的属性
int oldLast
的值为子字符串结束的索引+1的值,即4,下次执行find时,字符串从索引4开始匹配
3.3.2 Matcher.group()
public String group(int group)方法解析说明:
-
现存在一个字符串String content = "1234, 5678, 9012";
-
假设指定一个正则表达式 Pattern.compile("(\\d\\d)(\\d\\d)");
-
根据正则表达式,运行一次
find()
方法后定位到第一个满足规则的字符串"1234"
,根据正则表达式将其进行分组后的结果为"(12)(34)"
-
对matcher对象的属性
int[] groups
进行赋值-
groups[0] = 0记录子字符串开始的索引, group[1] = 4记录子字符串结束的索引+1,所以group[0]和group[1]表示子字符串在总字符串content的位置为[0, 4)
-
记录第一组()匹配到的字符串group[2] = 0, group[3] = 2
-
记录第二组()匹配到的字符串group[4] = 2, group[5] = 4
-
根据源码可知,函数会根据入参
int group
来计算第group组子字符串在总字符串中开始和结束的位置 -
简单来说,方法group(n)中,当 n = 0 时代表输出整个匹配到的字符串,而其他数字则代表正则表达式中的第n个括号,例如
group(1) = "12"
, 而group(2) = "34"
-
-
同时记录Matcher对象的属性
int oldLast
的值为子字符串结束的索引+1的值,即4。下次执行find时,字符串从索引4开始匹配
public String group(String name)方法解析说明:
作用同上,与上面不同的是入参由捕获编号group替换为正则表达式中定义的名称name
3.4 代码示例
public class RegexTest {
//表示匹配所有的数字与大小写字母
private static final Pattern pattern = Pattern.compile("\\w+");
public static String replaceTest(String str){
Matcher matcher = pattern.matcher(str);
//将所有的数字与大小写字母进行替换
return matcher.replaceAll("");
}
public static void main(String[] args) {
String str = "sd我fd23f是gdg一串jf中fgdf文";
System.out.println("替换前:" + str);
String result = replaceTest(str);
System.out.println("替换后:" + result);
}
}
运行结果:
更多优质技术分享,请关注下面👇👇👇[老马Hony]公众号