正则表达式:也称为正规表达式或简称为regex,是一种用来匹配喝操作字符串的表达式。可以通过一系列的字符和特殊符号来定义一个搜索模式,用于在文本中查找、替换、或者验证符合特定模式的内容。
正则表达式由普通字符(例如字母、数字、标点符号等)和特殊字符(元字符)组成。特殊字符具有特殊的含义和功能,用于描述模式中的各个部分。
.
:匹配除换行符以外的任意字符。*
:匹配前面的元素零次或多次。+
:匹配前面的元素一次或多次。?
:匹配前面的元素零次或一次。^
:匹配输入字符串的开始位置。$
:匹配输入字符串的结束位置。[]
:匹配括号内的任意一个字符。\
:转义字符,在特殊字符前加上\
可以取消其特殊含义。|
:逻辑或操作符,匹配符号左侧或右侧的模式之一。
正则表达式还支持一些特殊的元字符类别,如 \d
表示数字字符、\w
表示单词字符、\s
表示空白字符等。这些特殊的元字符类别提供了一种简写形式,用于表示常见的字符类型。
正则表达式在很多编程语言和工具中都有广泛应用,例如在文本编辑器中查找替换、验证用户输入、数据提取和模式匹配等场景。
1. 正则表达式实例:
一个字符串就是一个简单的正则表达式,
例如 Hello World 正则表达式匹配 "Hello World" 字符串。.(点号)也是一个正则表达式,它匹配任何一个字符如:"a" 或 "1"。
正则表达式 | 描述 |
---|---|
this is text | 匹配字符串 "this is text" |
this\s+is\s+text | 注意字符串中的 \s+。 匹配单词 "this" 后面的 \s+ 可以匹配多个空格,之后匹配 is 字符串,再之后 \s+ 匹配多个空格然后再跟上 text 字符串。 可以匹配这个实例:this is text |
^\d+(\.\d+)? | ^ 定义了以什么开始 \d+ 匹配一个或多个数字 ? 设置括号内的选项是可选的 \. 匹配 "." 可以匹配的实例:"5", "1.5" 和 "2.21"。 |
1.1 utill regex包
java.util.regex
是 Java 标准库中的一个包,用于支持正则表达式的处理。它提供了与正则表达式相关的类和接口,可以用于文本的匹配、搜索、替换等操作。
java.util.regex
包中的主要类和接口包括:
-
Pattern
类:用于表示正则表达式的编译表示。它提供了将正则表达式编译成可重用的模式对象的方法,并可以通过模式对象执行匹配操作。 -
Matcher
类:表示一个匹配器对象,用于在输入字符串中执行匹配操作。它提供了多种方法来执行匹配、查找、替换等操作,并可以获取匹配结果的相关信息。 -
MatchResult
接口:定义了匹配结果的一些方法,例如获取匹配到的子串、获取捕获组的值等。 -
PatternSyntaxException: PatternSyntaxException 是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
package Regex;
import org.junit.Test;
import java.util.Scanner;
public class demo1 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (true){
System.out.println("请输入账号");
String s1 = in.nextLine();
System.out.println(s1.matches("^[0-9]{6,12}$"));
// [0-9] 表示匹配一个数字字符。
// {6,12} 表示前面的元素(即数字字符)重复出现的次数范围,在此例中是 6 到 12 次。
}
}
@Test
public void test1(){
String s = "Java 是由 Sun Microsystems 公司于 1995 年 5 月推出的高级程序设计语言Java 可运行于多个平台,如 windows,Mac OS 及其他多种 UNIX 版本的系统";
// replace 查找替换
s = s.replaceAll("[a-zA-Z]+", "hello");
s = s.replaceAll("\\d+","world");
System.out.println(s);
}
@Test
public void test2() {
String s1 = "aaa,bbb,123,456,hello,word";
String [] arr = s1.split(",");
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
@Test
public void test3() {
String s2 = "hello12333world4567welcome34to4beijing";
String[] arrs2 = s2.split("\\d+");
for (int i = 0; i < arrs2.length; i++) {
System.out.println(arrs2[i]);
}
}
@Test
public void test4(){
String s3 = "123abc456def789ghi987jkl654mno321pqrstu12345vwxyz";
String[] arr3 = s3.split("\\d+");
for (int i = 0; i < arr3.length; i++) {
System.out.println(arr3[i]);
}
}
}
1.2 小练习:验证邮箱是否合法
控制台输入邮箱,编写邮箱匹配的正则表达式。 Pattern,将正则表达式编译为Pattern的对象,在将输入的邮箱用.matcher方法关联Matcher的对象。最后Boolean判断,并输出结果。
public static void main(String[] args) {
// 要验证的字符串
Scanner s1 = new Scanner(System.in);
System.out.println("请输入您的邮箱");
String str = s1.next();
// 邮箱验证规则
String regEx = "[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\\.){1,3}[a-zA-z\\-]{1,}";
// 编译正则表达式
Pattern pattern = Pattern.compile(regEx);
Matcher matcher = pattern.matcher(str);
// 字符串是否与正则表达式相匹配
boolean rs = matcher.matches();
System.out.println(rs);
}
2. Java正则表达式的语法
2.1 正则转义符
元符号-转义号\\
\\符号说明:在我们使用正则表达式去检索某些特殊字符的时候,需要用到转义字符,否则检测不到结果,甚至会报错。
需要用到转义符的字符有:. * + ( )$ / \ ? [ ] ^ { }
注意:在Java的正则表达式中,两个\\代表其他语言中的一个\
2.2 特殊字符
字符 | 解释 |
X | 字符x(x 可代表任何合法的字符) |
\0mnn | 八进制数 0mnn 所表示的字符 |
\xhh | 十六进制值 0xhh 所表示的字符 |
\uhhhh | 十六进制值 0xhhhh 所表示的 Unicode 字符 |
\t | 制表符(“\u0009”) |
\n | 新行(换行)符(‘\u000A’) |
\r | 回车符(‘\u000D’) |
\f | 换页符(‘\u000C’) |
\a | 报警(bell)符(‘\u0007’) |
\e | Escape 符(‘\u001B’) |
\cx | x 对应的的控制符。例如,\cM匹配 Ctrl-M。x 值必须为 A~Z 或 a~z 之一。 |
正则表达式中的特殊字符
特殊字符 | 说明 |
$ | 匹配一行的结尾。要匹配 $ 字符本身,请使用\$ |
^ | 匹配一行的开头。要匹配 ^ 字符本身,请使用\^ |
() | 标记子表达式的开始和结束位置。要匹配这些字符,请使用\(和\) |
[] | 用于确定中括号表达式的开始和结束位置。要匹配这些字符,请使用\[和\] |
{} | 用于标记前面子表达式的出现频度。要匹配这些字符,请使用\{和\} |
* | 指定前面子表达式可以出现零次或多次。要匹配 * 字符本身,请使用\* |
+ | 指定前面子表达式可以出现一次或多次。要匹配 + 字符本身,请使用\+ |
? | 指定前面子表达式可以出现零次或一次。要匹配 ?字符本身,请使用\? |
. | 匹配除换行符\n之外的任何单字符。要匹配.字符本身,请使用\. |
\ | 用于转义下一个字符,或指定八进制、十六进制字符。如果需匹配\字符,请用\\ |
| | 指定两项之间任选一项。如果要匹配丨字符本身,请使用\| |
预定义字符
预定义字符 | 说明 |
. | 可以匹配任何字符 |
\d | 匹配 0~9 的所有数字 |
\D | 匹配非数字 |
\s | 匹配所有的空白字符,包括空格、制表符、回车符、换页符、换行符等 |
\S | 匹配所有的非空白字符 |
\w | 匹配所有的单词字符,包括 0~9 所有数字、26 个英文字母和下画线_ |
\W | 匹配所有的非单词字符 |
方括号表达式
方括号表达式 说明 表示枚举 例如 [abc]表示 a、b、c 其中任意一个字符; [gz]表示 g、z 其中任意一个字符 表示范围:- 例如 [a-f]表示 a~f 范围内的任意字符; [\\u0041-\\u0056]表示十六进制字符 \u0041 到 \u0056 范围的字符。范围可以和枚举结合使用,如 [a-cx-z],表示 a~c、x~z 范围内的任意字符 表示求否:^ 例如 [^abc]表示非 a、b、c 的任意字符; [^a-f]表示不是 a~f 范围内的任意字符 表示“与”运算:&& 例如 [a-z&&[def]]是 a~z 和 [def] 的交集,表示 d、ef[a-z&&^bc]]是 a~z 范围内的所有字符,除 b 和 c 之外[ad-z] [a-z&&[m-p]]是 a~z 范围内的所有字符,除 m~p 范围之外的字符 表示“并”运算 并运算与前面的枚举类似。例如 [a-d[m-p]]表示 [a-dm-p]
补充:
Java正则表达式默认是区分字母大小写的,如要实现不区分大小写
(?i)abc表示abc都不区分大小写
a(?i)bc表示bc不区分大小写
a((?i)b)c表示只有b不区分大小写
Pattern pattern=Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
//当创建Pattern对象时,指定Pattern.CASE_INSENSITIVE,表示匹配不区分字母大小写
细节:Java匹配默认贪婪匹配,即尽可能匹配多的,比如"a{3,4}",表示匹配aaa或者aaaa,但是优先匹配aaaa,例如原字符串中包括"aaaaaa",匹配"a{3,4}"时,会找到"aaaa"
3. 正则捕获组
从正则表达式左侧开始,每出现一个左括号( 记作一个分组,编号从1开始,0代表整个表达式常用分组构造形式(pattern)
例如:
2017-04-25,表达式如下
(\\d{4})-((\\d{2})-(\\d{2}))
有 4 个左括号,所以有 4 个分组:
编号 | 捕获组 | 匹配 |
0 | (\d{4})-((\d{2})-(\d{2})) | 2017-04-25 |
1 | (\d{4}) | 2017 |
2 | ((\d{2})-(\d{2})) | 04-25 |
3 | (\d{2}) | 04 |
4 | (\d{2}) | 25 |