正则表达式
导包:java.util.regex
1、匹配规则
使用string类的matches方法
返回值为boolean 代表是否能匹配成功
public class ReTest {
// 电话号码的规范
// 起始位为1 第二位为3,4,5,6,7,8,9
public static boolean isRealPhone(String phone){
boolean flag = phone.matches("1[-9]\\d{9}");
return flag;
}
public static void main(String[] args) {
System.out.println(isRealPhone("11811730656"));
}
}
-
精确匹配
- 注意特殊符号需要转义,比如"+“要写成”\\+"
-
特殊符号:一些具有特殊含义的符号
正则符号 匹配规则 . 可以匹配任意一个字符 \d 可以匹配一个数字 \w 可以匹配一个字母、数字或者下划线 \s 可以匹配任意一个空白字符,比如空格、tab \D 可以匹配一个非数字 \W 可以匹配一个非字母、数字、下划线 \S 可以匹配一个非空白字符 -
修饰符:用来修饰前面的内容
正则符号 匹配规则 * 表示可以匹配任意个,前面的字符 + 表示至少匹配一个字符 ? 表示可以匹配0或1个字符 {n} | {l,r} 表示可以匹配n个字符或者是[l,r]的区间 [abc] 可以匹配中括号范围中的任意一个字符 [a-z0-9] 中括号可以指定一个或者多个范围 | 表示或者,只能匹配一个,可以加()进行范围限定 ^ &$ 表示字符串开头和结束 () 分组
2、分组
String和Pattern的对比
String中的mathces方法内部其实调用的是Pattern.mathcer,以下的两种方式相同
String:
String regex = "^1[-9]\\d{9}$";
String str = "12331231234";
boolean flag = str.matches(regex);
Pattern:
Pattern pattern = Pattern.compile("^1[-9]\\d{9}$");
Matcher matcher = pattern.matcher("12331231234");
boolean flag = matcher.matches();
使用String中的matches进行反复匹配的时候效率低,因为String内部每次都会编译一次,不如直接使用
pattern.matcher(str).matches()
分组
-
使用Matcher的group方法可以提取子串
-
使用前必须先判断是否匹配成功
-
group(0)表示匹配整个字符串,group(1)表示第一个()中的字符串
public class ReTest {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("^(\\d{4})\\-(\\d{1,2})\\-(\\d{1,2})$");
Matcher matcher = pattern.matcher("2022-05-26");
if(matcher.matches()){
String date = matcher.group(0);
String year = matcher.group(1);
String month = matcher.group(2);
}
}
}
3、非贪婪匹配
使用?来进行非贪婪匹配
当使用两个?的时候,第一个?表示匹配0-1个,第二个问号表示非贪婪匹配
public class ReTest {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("^(\\d*?)(0*)$");
Matcher matcher = pattern.matcher("1234000");
if(matcher.matches()){
String date = matcher.group(0);
String year = matcher.group(1);
String month = matcher.group(2);
System.out.println(year);
System.out.println(month);
}
}
}
4、字符串的分割和替换
(1)分割方法:
String[] String.split(String regex)
举例:
public class ReTest {
public static void main(String[] args) {
// 分割字符串
String s = "a,,b c;;d e,";
String res[] = s.split("[\\,\\s\\;]+");
for (String re : res) {
System.out.print(re+" ");
}
}
}
(2)搜索方法:
Mathcer.find()
举例:单词查找
public class ReTest {
public static void main(String[] args) {
// 分割字符串
String s = "hello world hello sdut hello jsj.";
Pattern pattern = Pattern.compile("\\w*",Pattern.CASE_INSENSITIVE);// 忽视大小写
Matcher matcher = pattern.matcher(s);
while(matcher.find()){
String sub = s.substring(matcher.start(),matcher.end());
System.out.println(sub);
}
}
}
(3)替换方法:
String.replaceAll(String regex,String s)
进阶用法
String res = s.replaceAll(String regex,"$1")
$1 代表前面正则表达式中的第一个分组
public class ReTest {
public static void main(String[] args) {
// 分割字符串
String s = "hello, world, hello sdut hello jsj.";
String res = s.replaceAll("(\\w+)","-$1-");
System.out.println(res);
}
}
5、例题:
Leetcode:468. 验证IP地址
地址:https://leetcode.cn/problems/validate-ip-address/
5-1 描述:
5-2 思路:
(1)如果正常String处理会非常麻烦,而且非常容易出错
(2)这里直接使用正则表达式,注意IPv4中三位数的情况,我这里是分了1XX、24X、25X三种情况,如果有更好的方法也可以评论区留言哇!
代码:
import java.util.regex.*;
class Solution {
public String validIPAddress(String queryIP) {
String res="Neither";
Pattern pattern1 = Pattern.compile("((\\d)|([1-9]\\d)|(1\\d{2}|2([0-4][0-9]|5[0-5])))(\\.((\\d)|([1-9]\\d)|(1\\d{2}|2([0-4][0-9]|5[0-5])))){3}");
Matcher matcher1= pattern1.matcher(queryIP);
if(matcher1.matches())res="IPv4";
Pattern pattern2 = Pattern.compile("[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4}){7}");
Matcher matcher2= pattern2.matcher(queryIP);
if(matcher2.matches())res="IPv6";
return res;
}
}