Java正则表达式

1. 正则表达式基本介绍

正则表达式(regular expression,简写为regex),Java提供了正则表达式技术,专门用于处理类似文本问题,就是用某种模式去匹配字符串的一个公式。换句话说,正则表达式是对字符串执行模式匹配的技术

2. 正则表达式语法

2.1 基本介绍

了解正则表达式中各种元字符的功能是灵活运用正则表达式的基础。
元字符从功能上可以分为:

  1. 限定符
  2. 定位符
  3. 字符匹配符
  4. 选择匹配符
  5. 分组组合和反向引用符
  6. 特殊字符

2.2 元字符

2.2.1 转义符 \\

说明:在使用正则表达式检索一些特殊字符时,需要用到转义符号。
提示Java的正则表达式中,两个斜杠 \\ 代表其他语言的一个
注意:几个需要用到转义符的字符有:* + ( ) $ / \ ? [ ] ^ { }
代码示例

import java.util.regex.Matcher;
import java.util.regex.Pattern;

//正则表达式_元字符_转义号
public class EX01 {
	public static void main(String[] args) {
		String content = "abc$(abc(123(";  
		//匹配( => \\(
		String regStr = "\\(";    //注意这里的双斜杠转义号
		
		//创建正则表达式对象
		Pattern pattern = Pattern.compile(regStr);
		
		//创建匹配器 matcher,按照 正则表达式的规则 去匹配 content 字符串
		Matcher matcher = pattern.matcher(content);
		
		//matcher.find() 会根据指定的规则,定位满足规则的子字符串
		//group(0) 表示匹配到的子字符串
		while(matcher.find()) {
			System.out.println("找到 " + matcher.group(0));
		}
	}
}

运行结果

找到 (
找到 (
找到 (

2.2.2 字符匹配符

符号含义示例解释匹配的输入示例
[ ]可接收的字符列表[abcd]a、b、c、d中任意一个字符a
[^]不接收的字符列表[^abc]除a、b、c之外的任意一个字符,包括数字与特殊符号d
-连字符A-ZA至Z中任意一个大写字母(包括A和Z)A
.匹配除 \n 以外的任何字符。 若要匹配 . 本身则需要使用 \\a…b以a开头,b结尾,中间为两个任意字符的长度为4的字符串abcb、a12b、a*#b
\\d匹配单个数字字符,相当于[0-9]\\d\\d\\d包含3个数字的字符串123
\\D匹配单个数字字符,相当于[^0-9]\\D(\\d)*以单个非数字字符开头,后接任意个数数字字符串a、A123
\\w匹配单个数字、大小写字母字符,相当于[0-9a-zA-Z]\\w\\w\\w长度为3的数字字母字符串12a、bDc
\\W匹配单个数字、大小写字母字符,相当于[^0-9a-zA-Z]\\W + \\d{2}以至少1个非数字字母字符开头、2个数字字符结尾的字符串#12、@#23

代码示例:(此处只示范了[a-z],其余类似,可自行尝试)

import java.util.regex.Matcher;
import java.util.regex.Pattern; 

//正则表达式_元字符_字符匹配符
public class EX02 {
	public static void main(String[] args) {
		String content = "a2cd6"; 
		
		//匹配 a-z 之间任意一个字符
		String regStr = "[a-z]";
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(content);
		
		while(matcher.find()) {
			System.out.println("找到 " + matcher.group(0));
		}
	}
}

运行结果

找到 a
找到 c
找到 d

2.2.3 选择匹配符

符号含义示例解释匹配的输入示例
|匹配 “|” 之前或之后的表达式ab|cdab或者cdab、cd

2.2.4 限定符

用于指定其前面的字符和组合项连续出现多少次

符号含义示例解释匹配的输入示例
*指定字符重复0次或n次(abc)*仅包含任意个abc的字符串abc、abcabc
+指定字符重复1次或n次(至少1次)m + (abc)*以至少1个m开头,后接任意个abc的字符串mabc、mabcabc
?指定字符重复0次或1次(至多1次)m + (abc)?以至少1个m开头,后接0个或1个abc的字符串mabc、mm
{n}只能输入n个字符[abcd]{3}由abcd中任意字母组成的长度为3的字符串abc、acd、bcd
{n,}至少指定n个匹配[abcd]{3,}由abcd中字母组成的任意长度不小于3的字符串aab、abd、bbbdca
{n,m}至少指定n个但不多于m个匹配[abcd]{3,5}由abcd中字母组成的任意长度不小于3,不大于5的字符串abcd、aabbc

代码示例: (此处只示范了a{3,4},其余类似,可自行尝试)

import java.util.regex.Matcher;
import java.util.regex.Pattern;

//正则表达式_元字符_限定符
public class EX03 {
	public static void main(String[] args) {
		String content = "1122aaaaaahelloworld"; 
		
		//注意: java匹配默认贪婪匹配,即尽可能匹配多的
		String regStr = "a{3,4}";  //表示匹配 aaa 或 aaaa
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(content);
		
		while(matcher.find()) {
			System.out.println("找到 " + matcher.group(0));
		}		
	}
}

运行结果

找到 aaaa

2.2.5 定位符

用于规定要匹配的字符串出现的位置

符号含义示例解释匹配的输入示例
^指定的起始字符^[0-9]+[a-z]*以至少1个数字开头,后接任意个小写字母的字符串123、4abc、55cde
$指定结束字符^[0-9]+[a-z]+$以至少1个数字开头,并以至少1个小写字母结尾的字符串1a、123a
\\b匹配目标字符串的边界ke\\b边界指的是字串间有空格或是该目标字符串的结束位置kexueke nke
\\B匹配目标字符串的非边界ke\\B与\b相反kexueke nke

2.3 非贪婪匹配

符号解释
?当该字符紧跟其他限定符后面时,匹配模式为“非贪婪的”。即匹配搜索到的尽可能短的字符串。例如:在字符串“1111”中,“1+?”只匹配单个“1”,而“1+”匹配所有“1” 。

2.4 分组、捕获、反向引用

概念介绍

  • 分组
    可以用一个圆括号组成一个匹配模式,这样一个圆括号中的部分我们可以看作是 一个分组。
  • 捕获
    把分组匹配的内容保存到内存中以数字编号显式命名的组里,方便之后引用。组0表示整个表达式,第一个出现的分组为组1,第二个为组2,以此类推。
  • 反向引用
    圆括号的内容被捕获后,之后便可以被使用,这个就叫反向引用。在正则表达式内部的反向引用 \\分组号外部反向引用 $分组号
常用的分组构造形式解释
(pattern)非命名捕获。捕获匹配的子字符串,编号从0开始
(?<\name>pattern)命名捕获。将匹配的子字符串捕获到1个组名称或编号名称中,用于name的字符串不能包含标点符号,且不能以数字开头

代码示例:(此处示范 匹配4个连续的相同数字

import java.util.regex.Matcher;
import java.util.regex.Pattern;

//正则表达式_反向引用
public class EX04 {
	public static void main(String[] args) {
		String content = "1111222abcdddd3333hello";  //目标字符串
		
		//匹配连续4个的相同数字
		String regStr = "(\\d)\\1{3}";   //正则表达式字符串
		Pattern pattern = Pattern.compile(regStr);
		Matcher matcher = pattern.matcher(content); 
			
		while(matcher.find()) {  
			System.out.println("找到 " + matcher.group(0));
		}		
	}
}

运行结果

找到 1111
找到 3333

2.5 三个常用类

java.util.regex 包主要包括以下3个常用类

  • Pattern 类
    pattern 类没有公共构造方法,要创建一个 pattern 对象,调用其公共静态方法,它返回一个 pattern 对象。该方法接受一个正则表达式作为它的第一个参数。例如: Pattern r = Pattern.compile(pattern);

  • Matcher类
    Matcher 对象是对输入字符串进行解释和匹配的引擎。Matcher 也没有公共构造方法。需调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

  • PatternSyntaxException
    PatternSyntaxException 是一个非强制性异常类,它表示一个正则表达式模式中的语法错误。

3. 应用示例

3.1 示例1-电话号码

要求验证输入的电话号码的格式是否正确
格式规定:必须以13,14,15,18 开头的11位数,比如 13550358888
(读者可根据自己的需求灵活变通,此处只是举个例子,不代表所有情况)

代码实现

import java.util.Scanner;
import java.util.regex.Pattern;

//正则表达式_电话号码
public class EX07 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		
		//输入需要判断的电话号码
		System.out.print("Enter Phone number: ");
		String content = input.nextLine();
		
		//要求必须以13,14,15,18 开头的11位数
		String regStr = "^1[3|4|5|8]\\d{9}$";
		
		//判断格式是否正确
		System.out.println("The number is: " + Pattern.matches(regStr, content));
		
		input.close();
	}
}

运行结果

Enter Phone number: 13550358888
The number is: true

3.2 示例2-电子邮件

要求验证输入的电子邮件格式是否合法
格式规定

  1. 只能有一个@
  2. @前面是用户名,可以是 a-z A-Z 0-9 _ - 字符
  3. @后面是域名,且只能为英文字母,如 bilibili.com

代码实现

import java.util.Scanner;
import java.util.regex.Pattern;

//正则表达式_电子邮件
public class EX08 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		
		//输入需要判断的电子邮件
		System.out.print("Enter email: ");
		String content = input.nextLine();
		
		String regStr = "[\\w-]+@([a-zA-Z]+\\.)+[a-zA-Z]+";
		
		//判断格式是否正确
		System.out.println("The email is: " + Pattern.matches(regStr, content));
		
		input.close();
	}
}

运行结果

Enter email: java@abcd.com
The email is: true

4. String类中使用正则表达式

4.1 替换字符串

String 类中包含的 replaceAll 方法可以替换所有匹配的字符串。

代码示例:(此处演示使用正则表达式来替换字符串)

//正则表达式_替换字符串
public class EX05 {
	public static void main(String[] args) {
		String content = "Java8abcdJava11defgjava";  
		
		//使用正则表达式,将Java8和Java11替换成Java
		content = content.replaceAll("Java8|Java11", "Java");
		
		//输出替换后的字符串
		System.out.println(content);
	}
}

运行结果

JavaabcdJavadefgjava

4.2 分割字符串

String 类 public String[] split(String regex)

代码示例:(此处演示 如何按照 - 或者 ~ 或者 数字 来分割字符串)

//正则表达式_分割字符串
public class EX06 {
	public static void main(String[] args) {
		String content = new String("jike~hello-world234java");
		
		//要求按照 - 或者 ~ 或者 数字 来分割
		String[] split = content.split("-|~|\\d+");
		
		for(String s : split) {
			System.out.println(s);
		}
	}
}

运行结果

jike
hello
world
java

以上为个人自学笔记,学习并借鉴了视频:https://www.bilibili.com/video/BV1Eq4y1E79W?p=1
以及Java黑皮书: Java语言程序设计与数据结构 基础篇

若有不足,欢迎指正!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值