正则表达式是计算机科学的一个概念,通常用于检索。替换符合某个规则的文本。使用正则表达式,我们能够以编程的方式,构造复杂的文本模式,并对输入的字符串进行搜索。一旦找到了匹配这些模式的部分,就能对其进行进一步的处理。
简单示例
public class Main {
public static void main(String[] args) {
//匹配带正号的数值
System.out.println("+123".matches("\\+\\d+"));
String str = "12321asdf1231dsfe532";
//按英文字符分割
for (String tmp : str.split("[a-zA-Z]+")) {
System.out.println(tmp);
}
}
}
输出
true
12321
1231
532
基础
正则表达式其实就是以某种方式来描述字符串。与其他的语言有所不同,“\”在其他语言的正则表达式中通常表示一个普通的反斜杠,而在Java中,其表示一个正则表达式的反斜杠,其后的字符就有特殊意义。举例来说,“\\”表示一个普通的反斜杠,“\d”表示一位数字。其中换行和制表符之类的是特例,直接使用“\n\r”即可。
创建正则表达式
列举部分常用的构造集。
字符
正则表达式 | 含义 |
---|---|
B | 表示字符B |
\xhh | 十六进制值为oxhh的字符 |
\uhhhh | 十六进制表示为oxhhhh的Unicode字符 |
\t | 制表符 |
\n | 换行符 |
\r | 回车 |
字符类
正则表达式 | 含义 |
---|---|
[abc] | abc任意字符 |
[^abc] | abc之外的任意字符 |
[a-zA-Z] | a到z或A到Z范围内的字符 |
[abc[hij]] | abchij任意字符 |
[a-z&&[hij]] | hij任意字符(交集) |
\s | 空白符(空格、tab、换行、换页和回车) |
\S | 非空白符,同[^\s] |
\d | 任意数字,同[0-9] |
\D | 非数字,同[^0-9] |
\w | 词字符[a-zA-Z0-9] |
\W | 非词词汇,同[^\w] |
逻辑操作符
正则表达式 | 含义 |
---|---|
XY | Y跟在X后面 |
X|Y | X或Y |
(X) | 捕获组。可以在表达式中用\i引用第i个捕获组 |
边界匹配符
正则表达式 | 含义 |
---|---|
^ | 一行的起始 |
$ | 一行的结束 |
\b | 词的边界 |
\B | 非词的边界 |
\G | 前一个匹配的结束 |
限定词
正则表达式 | 含义 |
---|---|
X? | 一个或零个X |
X* | 零个或多个X |
X+ | 一个或多个X |
X{n} | 恰好n次X |
X{n,} | 至少n次X |
X{n,m} | X至少n次,且不超过m次 |
表达式X通常应该用圆括号括起来,以便它能够按照预期的效果执行。
Pattern和Matcher
Java中除了使用String类来使用正则表达式,还提供了功能更为强大的Pattern和Matcher类。一般的使用方法为:
1. 使用Pattern.compile()方法
,根据提供的String类型的正则表达式生成Pattern对象。
2. 将需要检索的字符串传入Pattern对象的matcher()方法
,生成Matcher对象。
3. 使用Matcher对象进行操作。
简单示例
public class Main {
public static void main(String[] args) {
//获取英文单词
String str = "apple banana orange";
Pattern pattern = Pattern.compile("[a-zA-Z]+");
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group() + " start:"
+ matcher.start() + " end:" + matcher.end());
}
}
}
输出
apple start:0 end:5
banana start:6 end:12
orange start:13 end:19
Matcher
start()、end()
在匹配成功后,start()返回先前匹配的起始位置的索引,而end()返回所匹配的最后字符的索引位置加一的值。
matchers()
matchers()方法用于判断整个输入字符串是否匹配正则表达式。上述例子中执行System.out.println(matcher.matches());
,将输出false
。
lookingAt()
lookingAt()方法用于判断该字符串的起始部分是否匹配模式。上述例子中执行System.out.println(matcher.lookingAt());
,将输出true
。
find()
find()方法类似迭代器中的next(),向前遍历输入字符串。
find(int start)
find(int start)能够接受一个整数参数,该整数表示字符串中字符的位置,并以其作为搜索起点。将上述例子修改:
public class Main {
public static void main(String[] args) {
//获取英文单词
String str = "apple banana orange";
Pattern pattern = Pattern.compile("[a-zA-Z]+");
Matcher matcher = pattern.matcher(str);
if (matcher.find(2)) {
System.out.println(matcher.group());
}
}
}
输出
ple
组(group)
组是用括号划分的正则表达式,可以根据组的编号来引用某个组。组号为0表示整个正则表达式,组号为1表示被第一对括号括起的组,以此类推。以A(B(C))D
为例,共三个组,组0为ABCD,组1为BC,组2为C。
groupCount()
groupCount()返回该匹配器的模式中的分组数目,第0组不包括在内。
group()
group()返回前一次匹配操作的第0组。
group(int i)
group(int i)返回在前一次匹配操作期间指定的组。下面是简单的示例,第1组为\\d+
。
public class Main {
public static void main(String[] args) {
String str = "apple123banana";
Pattern pattern = Pattern.compile("[a-zA-Z]+(\\d+)[a-zA-Z]+");
Matcher matcher = pattern.matcher(str);
System.out.println(matcher.groupCount());
if (matcher.find()) {
System.out.println(matcher.group(1));
}
}
}
输出
1
123