持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
一、概念
正则表达式可以用字符串来描述规则,并用来匹配字符串。例如,判断手机号,我们用正则表达式\d{11}:
boolean isValidMobileNumber(String s) {
return s.matches("\d{11}");
}
Java标准库的java.util.regex包内置了正则表达式引擎,注意Java字符串用\表示``。
二、匹配规则
匹配任意字符:.
匹配数字:\d
匹配非数字:\D
匹配常用字符(字母、数字或下划线):\w
匹配非常用字符:\W
匹配空格字符(空格、Tab):\s
匹配非空格字符:\S
重复匹配
修饰符*可以匹配任意个字符,包括0个字符
修饰符+可以匹配至少一个字符
修饰符?可以匹配0个或一个字符
修饰符{n}精确指定n个字符
修饰符{n,m}指定匹配n~m个字符
修饰符{n,}可以匹配至少n个字符
三、复杂匹配规则
匹配开头和结尾:^表示开头,$表示结尾
匹配指定范围:[...]可以匹配范围内的字符,[1-9],[0-9a-fA-F]
不包含指定范围的字符:[^...]
或规则匹配:用|连接的两个正则规则
使用括号:可以把公共部分提出来,然后用(...)把子规则括起来表示成learn\s(java|php|go)
四、分组匹配
用(...)先把要提取的规则分组,没办法用String.matches()这样简单的判断方法了,必须引入java.util.regex包,用Pattern对象匹配,匹配后获得一个Matcher对象,如果匹配成功,就可以直接从Matcher.group(index)返回子串
要特别注意,Matcher.group(index)方法的参数用1表示第一个子串,2表示第二个子串。如果我们传入0会得到什么呢?答案是010-12345678,即整个正则匹配到的字符串。
使用Matcher时,必须首先调用matches()判断是否匹配成功,匹配成功后,才能调用group()提取子串。
五、非贪婪匹配
正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配。
给定一个匹配规则,加上?后就变成了非贪婪匹配。
六、搜索和替换
分割字符串
使用正则表达式分割字符串可以实现更加灵活的功能。String.split()方法传入的正是正则表达式。我们来看下面的代码:
"a b c".split("\s"); // { "a", "b", "c" }
"a b c".split("\s"); // { "a", "b", "", "c" }
"a, b ;; c".split("[\,\;\s]+"); // { "a", "b", "c" }
搜索字符串
获取到Matcher对象后,不需要调用matches()方法(因为匹配整个串肯定返回false),而是反复调用find()方法,在整个串中搜索能匹配上\wo\w规则的子串,并打印出来。这种方式比String.indexOf()要灵活得多,因为我们搜索的规则是3个字符:中间必须是o,前后两个必须是字符[A-Za-z0-9_]。
替换字符串
使用正则表达式替换字符串可以直接调用String.replaceAll(),它的第一个参数是正则表达式,第二个参数是待替换的字符串。
反向引用
如果我们要把搜索到的指定字符串按规则替换,比如前后各加一个<b>xxxx</b>,这个时候,使用replaceAll()的时候,我们传入的第二个参数可以使用$1、$2来反向引用匹配到的子串
package com.study.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexDemo {
public static void main(String[] args) {
demo1();
System.out.println("==================================");
demo2();
System.out.println("==================================");
demo3();
System.out.println("==================================");
demo4();
System.out.println("==================================");
demo5();
}
private static void demo1() {
String regex = "20\d\d";
System.out.println("2019".matches(regex));
System.out.println("2100".matches(regex));
System.out.println("=====================");
String re1 = "a\&c"; // 对应的正则是a&c
System.out.println("a&c".matches(re1));
System.out.println("a-c".matches(re1));
System.out.println("a&&c".matches(re1));
System.out.println("=====================");
String re2 = "a\u548cc"; // 中文用\u####的十六进制表示
System.out.println("a和c".matches(re2));
System.out.println("=====================");
String re3 = "java|php";
System.out.println("java".matches(re3));
System.out.println("php".matches(re3));
System.out.println("go".matches(re3));
System.out.println("=====================");
String re4 = "learn\s(java|php|go)";
System.out.println("learn java".matches(re4));
System.out.println("learn Java".matches(re4));
System.out.println("learn php".matches(re4));
System.out.println("learn Go".matches(re4));
}
private static void demo2() {
Pattern p = Pattern.compile("(\d{3,4})-(\d{7,8})");
Matcher m = p.matcher("010-12345678");
if (m.matches()) {
String g0 = m.group(0); // 0表示匹配的整个字符串
String g1 = m.group(1); // 1表示匹配的第1个子串
String g2 = m.group(2); // 2表示匹配的第2个子串
System.out.println(g0);
System.out.println(g1);
System.out.println(g2);
} else {
System.out.println("匹配失败!");
}
}
// 非贪婪匹配
private static void demo3() {
Pattern pattern = Pattern.compile("(\d+?)(0*)");
Matcher matcher = pattern.matcher("1230000");
if (matcher.matches()) {
System.out.println("group1=" + matcher.group(1)); // "123"
System.out.println("group2=" + matcher.group(2)); // "0000"
}
}
private static void demo4() {
String s = "the quick brown fox jumps over the lazy dog.";
Pattern p = Pattern.compile("\wo\w");
Matcher m = p.matcher(s);
while (m.find()) {
String sub = s.substring(m.start(), m.end());
System.out.println(sub); // row fox dog
}
}
private static void demo5() {
String s = "The quick\t\t brown fox jumps over the lazy dog.";
String r = s.replaceAll("\s+", " ");
System.out.println(r); // "The quick brown fox jumps over the lazy dog."
r = r.replaceAll("\s([a-z]{4})\s", " <b>$1</b> ");
System.out.println(r); // The quick brown fox jumps <b>over</b> the <b>lazy</b> dog.
}
}