Java基础11:正则表达式
一、匹配规则 1. 字符类(只匹配一个字符) 2. 预定义字符(只匹配一个字符) 3. 数量词
二、Pattern 三、Matcher 四、在字符串方法中的使用 1. matches 2. replaceAll 3. split
五、 Pattern+Matcher示例
六、贪婪爬取和非贪婪爬取
七、捕获分组和非捕获分组 1. 非捕获分组 2. 内部使用捕获分组 3. 外部使用捕获分组
一、匹配规则
|
表示或者:[X|x]
X或者x(?i)
表示忽略大小写:a((?i)b)c
ac小写,B忽略大小写&&
表示两个范围的交集,如果只是一个&
代表匹配一个&符号
1. 字符类(只匹配一个字符)
正则表达式 说明 [abc]
只匹配一个a,b,c [^abc]
除了a,b,c之外的任何字符 [a-zA-Z]
a-z或A-Z之间的任何字符 [a-d[m-p]]
a-d或m-p之间的任何字符 [a-z&&[def]]
a-z和def的交集,为d,e,f [a-z&&[^bc]]
a-z和非b、c的交集,等同于[ad-z]
[a-z&&[^m-p]]
a-z和除了m-p的交集,等同于[a-lq-z]
2. 预定义字符(只匹配一个字符)
正则表达式 说明 .
任何字符 \d
一个数字:[0-9]
\D
非数字:[^0-9]
\s
一个空白字符:[\t\n\x0B\f\r]
\S
非空白字符:[^\s]
\w
英文、数字、下划线:[a-zA-Z_0-9]
\W
一个非单词字符:[^\w]
3. 数量词
正则表达式 说明 X? X出现一次或0次(最多一次) X* X出现0次或多次(可有可无) X+ X出现一次或多次(至少一次) X{n} X正好出现n次 X{n, } X至少出现n次,无上限 X{n,m} X至少出现n次但不超过m次
二、Pattern
Pattern表示正则表达式。 获取正则表达式对象:Pattern p = pattern.compile("Java\\d{0,2}");
三、Matcher
Matcher表示文本匹配器。 按照正则表达式的规则去读取字符串,从头开始读取,在字符串中寻找符合匹配规则的子串。 获取文本匹配器对象:Matcher m = p.matcher(str);
获取是否有文本匹配:boolean b = m.find();
四、在字符串方法中的使用
方法名 返回类型 说明 matches(String regex) String[] 判断字符串是否满足正则表示规则 replaceAll(String regex, String newStr) String 按照正则表达式的规则进行替换 split(String regex) String[] 按照正则表达式的规则切割字符串
1. matches
格式:字符串.matches(正则表达式);
作用:
检验字符串是否满足规则 在一段文本中查找满足要求的内容
public class Demo2 {
public static void main ( String [ ] args) {
String regex1 = "1[3-9]\\d{9}" ;
System . out. println ( "13123456789" . matches ( regex1) ) ;
System . out. println ( "15712345678" . matches ( regex1) ) ;
System . out. println ( "131548582l" . matches ( regex1) ) ;
System . out. println ( "110" . matches ( regex1) ) ;
String regex2 = "0\\d{2,3}-?[1-9]\\d{4,9}" ;
System . out. println ( "020-2341234" . matches ( regex2) ) ;
System . out. println ( "02021234" . matches ( regex2) ) ;
System . out. println ( "027-41234" . matches ( regex2) ) ;
System . out. println ( "0202-2341234" . matches ( regex2) ) ;
String regex3 = "\\w+@[\\w&&[^_]]{2,6}(\\.[a-zA-Z]{2,3}){1,2}" ;
System . out. println ( "323232@qq.com" . matches ( regex3) ) ;
System . out. println ( "zhangsan@163.com" . matches ( regex3) ) ;
System . out. println ( "zj003@pci.com.cn" . matches ( regex3) ) ;
}
}
2. replaceAll
public class Demo6 {
public static void main ( String [ ] args) {
String s = "蔡徐坤fabdb2515sba肖战csnabdwa1212鹿晗" ;
String result1= s. replaceAll ( "[\\w&&[^_]]+" , "vs" ) ;
System . out. println ( result1) ;
}
}
3. split
import java. util. Arrays ;
public class Demo6 {
public static void main ( String [ ] args) {
String s = "坤坤fabdb2515sba战战csnabdwa1212鹿鹿" ;
String [ ] result = s. split ( "[\\w&&[^_]]+" ) ;
System . out. println ( Arrays . toString ( result) ) ;
}
}
五、 Pattern+Matcher示例
1. 爬取数据
import java. util. regex. Matcher ;
import java. util. regex. Pattern ;
public class Demo3 {
public static void main ( String [ ] args) {
String str = "Java有Java8和Java11的长期维护版,最新版是Java19" ;
Pattern p = Pattern . compile ( "Java\\d{0,2}" ) ;
Matcher m = p. matcher ( str) ;
while ( m. find ( ) ) {
System . out. println ( m. group ( ) ) ;
}
}
}
2. 有条件的爬取数据
package day16. regex ;
import java. util. regex. Matcher ;
import java. util. regex. Pattern ;
public class Demo4 {
public static void main ( String [ ] args) {
String str = "Java有Java8和Java11的长期维护版,最新版是Java19" ;
System . out. println ( "---------只要Java,不显示版本号---------" ) ;
String regex1 = "Java(?=\\d+)" ;
test ( str, regex1) ;
System . out. println ( "---------只显示有版本号的Java---------" ) ;
String regex2 = "Java(?:\\d+)" ;
test ( str, regex2) ;
System . out. println ( "---------只显示没有版本号的Java---------" ) ;
String regex3 = "Java(?!\\d+)" ;
test ( str, regex3) ;
}
private static void test ( String str, String regex) {
Pattern compile = Pattern . compile ( regex) ;
Matcher matcher = compile. matcher ( str) ;
while ( matcher. find ( ) ) {
System . out. println ( matcher. group ( ) ) ;
}
}
}
六、贪婪爬取和非贪婪爬取
贪婪爬取:爬取数据时尽可能的多获取数据 非贪婪爬取:爬取数据时尽可能的少获取数据 +?
、*?
表示非贪婪爬取。Java中,默认是贪婪爬取,如果要非贪婪爬取需要在数量词后面加上问号。
1. 贪婪爬取
import java. util. regex. Matcher ;
import java. util. regex. Pattern ;
public class Demo5 {
public static void main ( String [ ] args) {
String str = "Javaaaaaaaaabbbbbbbbaaaaaaaaaa有Java8和Java11的长期维护版,最新版是Java19" ;
Pattern p = Pattern . compile ( "ab+" ) ;
Matcher m = p. matcher ( str) ;
while ( m. find ( ) ) {
System . out. println ( m. group ( ) ) ;
}
}
}
2. 非贪婪爬取
import java. util. regex. Matcher ;
import java. util. regex. Pattern ;
public class Demo5 {
public static void main ( String [ ] args) {
String str = "Javaaaaaaaaabbbbbbbbaaaaaaaaaa有Java8和Java11的长期维护版,最新版是Java19" ;
Pattern p = Pattern . compile ( "ab+?" ) ;
Matcher m = p. matcher ( str) ;
while ( m. find ( ) ) {
System . out. println ( m. group ( ) ) ;
}
}
}
七、捕获分组和非捕获分组
作用:用于后续还要继续使用本组的数据。 由()
扩起来看成一组。 每组都有组号,组号从1开始,以左括号为基准,连续不间断。 使用捕获分组:
1. 非捕获分组
分组之后不需要再用本组数据,仅仅把数据扩起来。 特点:不占用组号。
符号 含义 举例 (?:正则)
获取所有 Java(?:8|11|19)
(?=正则)
获取前面部分 Java(?=8|11|19)
(?!正则)
获取不是指定内容的前面部分 Java(?!8|11|19)
2. 内部使用捕获分组
public class Demo7 {
public static void main ( String [ ] args) {
String regex1 = "(.).+\\1" ;
System . out. println ( "a123a" . matches ( regex1) ) ;
System . out. println ( "17891" . matches ( regex1) ) ;
System . out. println ( "&123&" . matches ( regex1) ) ;
System . out. println ( "a123b" . matches ( regex1) ) ;
String regex2 = "(.+).+\\1" ;
System . out. println ( "abc123abc" . matches ( regex2) ) ;
System . out. println ( "1^&7891^&" . matches ( regex2) ) ;
System . out. println ( "123123123" . matches ( regex2) ) ;
System . out. println ( "abc123bcd" . matches ( regex2) ) ;
String regex3 = "((.)\\2*).+\\1" ;
System . out. println ( "aaa123aaa" . matches ( regex3) ) ;
System . out. println ( "111789111" . matches ( regex3) ) ;
System . out. println ( "&&&123&&&" . matches ( regex3) ) ;
System . out. println ( "aab123aab" . matches ( regex3) ) ;
}
}
3. 外部使用捕获分组
public class Demo8 {
public static void main ( String [ ] args) {
String str = "我要学学编编编程程程程程" ;
String result = str. replaceAll ( "(.)\\1+" , "$1" ) ;
System . out. println ( result) ;
}
}