前面我们已经学习到 python的正则表达式,同样Java也能使用正则表达式,两者之间的表达式规则大同小异。
正则表达式是一套标准,它可以用于任何语言。Java标准库的java.util.regex包内置了正则表达式引擎,在Java程序中使用正则表达式非常简单
注意Java字符串用\\表示\。比如正常的202\d\d
,在Java中则写作为202\\d\\d
正则表达式也有特殊字符,比如转义字符\
,对于正则表达式a\&c
来说,对应的Java字符串是a\\&c
,因为\
也是Java字符串的转义字符,两个\\
实际上表示的是一个\
:
透过现象看本质,Java与python正则表达式关于正则表达式的使用方法是相同的,可以参考使用,注意Java字符串用\\
表示\
正则表达式 | 规则 | 可以匹配 |
---|---|---|
A | 指定字符 | A |
\u548c | 指定Unicode字符 | 和 |
. | 任意字符 | a,b,&,0 |
\d | 数字0~9 | 0~9 |
\w | 大小写字母,数字和下划线 | a~z,A~Z,0~9,_ |
\s | 空格、Tab键 | 空格,Tab |
\D | 非数字 | a,A,&,_,…… |
\W | 非\w | &,@,中,…… |
\S | 非\s | a,A,&,_,…… |
A* | 任意个数字符 | 空,A,AA,AAA,…… |
A+ | 至少1个字符 | A,AA,AAA,…… |
A? | 0个或1个字符 | 空,A |
A{3} | 指定个数字符 | AAA |
A{2,3} | 指定范围个数字符 | AA,AAA |
A{2,} | 至少n个字符 | AA,AAA,AAAA,…… |
A{0,3} | 最多n个字符 | 空,A,AA,AAA |
^ | 开头 | 字符串开头 |
$ | 结尾 | 字符串结束 |
[ABC] | […]内任意字符 | A,B,C |
[A-F0-9xy] | 指定范围的字符 | A,……,F,0,……,9,x,y |
[^A-F] | 指定范围外的任意字符 | 非A~F |
String.matches(regex)方法:只能匹配目标字符串是否满足给定的正则表达式规则,返回值是Boolean类型
public class Main {
public static void main(String[] args) {
String re1 = "java\\d"; // 对应的正则是java\d
System.out.println("java9".matches(re1));
System.out.println("java10".matches(re1));
System.out.println("javac".matches(re1));
String re2 = "java\\D";
System.out.println("javax".matches(re2));
System.out.println("java#".matches(re2));
System.out.println("java5".matches(re2));
}
}
分组匹配
我们前面讲到的(…)可以用来把一个子规则括起来,这样写learn\s(java|php|go)就可以更方便地匹配长字符串了。
实际上(…)还有一个重要作用,就是分组匹配。
前面已经了解到String.matches(regex)来判断是否满足目标正则表达式。但是如何提取匹配的子串?这就必须引入java.util.regex包,用Pattern对象匹配,匹配后获得一个Matcher对象,如果匹配成功,就可以直接从Matcher.group(index)返回子串:
public class Main {
public static void main(String[] args) {
// 编译解析规则
Pattern p = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");
// 待匹配的字符
Matcher m = p.matcher("010-12345678");
if (m.matches()) {
String g1 = m.group(1);
String g2 = m.group(2);
System.out.println(g1);
System.out.println(g2);
} else {
System.out.println("匹配失败!");
}
}
}
运行上述代码,会得到两个匹配上的子串010和12345678。
要特别注意,Matcher.group(index)方法的参数用1表示第一个子串,2表示第二个子串。如果我们传入0会得到什么呢?答案是010-12345678,即整个正则匹配到的字符串。
搜索和替换
public class Main {
public static List<String> regexFind(){
// 目标字符串
String s = "the quick brown fox jumps over the lazy dog.";
// 正则表达式编译模板
Pattern p = Pattern.compile("\\wo\\w");
// 编译获取Matcher对象
Matcher m = p.matcher(s);
// 创建ArrayList集合,用于存储
List<String> list = new ArrayList<>();
// 反复调用find()方法
while (m.find()) {
// 在整个串中搜索能匹配上\\wo\\w规则的子串
String sub = s.substring(m.start(), m.end());
// 将所有的字串添加到集合中
list.add(sub);
}
return list;
}
public static void main(String[] args) {
// 调用regexFind()方法
List<String> demo = regexFind();
System.out.println(demo);
System.out.println(demo.get(0));
System.out.println(demo.get(1));
System.out.println(demo.size());
/* 运行结果:
[row, fox, dog]
row
fox
3
*/
}
}
我们获取到Matcher对象后,不需要调用matches()方法(因为匹配整个串肯定返回false),而是反复调用find()方法
替换字符串
使用正则表达式替换字符串可以直接调用String.replaceAll()
,它的第一个参数是正则表达式,第二个参数是待替换的字符串。举例说明:
语言格式:strings.replaceAll(“正则表达式规则”,a) 用a替换strings里面的正则表达式规则
public class Main{
public static void main(String[] args){
String s = "the quick brown fox jumps over the lazy dog.";
return s.replaceAll("\\s+","--");
// 运行结果: the--quick--brown--fox--jumps--over--the--lazy--dog.
}
}