正则表达式是一种强大而灵活的文本处理工具,使用正则表达式能够以编程的方式构造复杂的文本模式,并对输入的字符串进行搜索,简单来说,正则表达式就是以某种方式来描述字符串。
一、基本语法
语法 | 语法解释 |
---|---|
普通字符(字母、数字、汉字、下划线) | 一个普通字符在表达式中只匹配与之相同的一个字符。 |
\t 、\n 、\t 、\f |
表示回车符、换行符、制表符、换页符。 |
[ 与 ] |
使用 [] 括起来的为一个可选字符组,表示其中包含的一系列字符中任意一个字符。例如 [abc] 表示 a、b、c 中的任意一个字符; [a-z] 表示字符 a 到字符 b 中的任意一个字符,其中 - 表示一个范围。 |
[^ 与 ] |
表示一个可选字符组的补集。例如 [^abc] 表示 a、b、c 之外的任意一个字符。 |
. |
表示除换行符以外的任意一个字符。 |
\d 与 \D |
\d 表示 0-9 之间的任意一个字符;\D 表示 0-9 之外的任意一个字符。 |
\s 与 \S |
\s 表示包括空格、制表符、换页符等空白字符的其中任意一个字符;\S 表示空白字符以外的任意一个字符。 |
\w 与 \W |
\w 表示字母、数字、下划线中的任意一个字符;\W 表示字母、数字、下划线之外的任意一个字符。 |
^ |
该符号不匹配任何字符,其匹配字符串开始的地方。 |
$ |
该符号不匹配任何字符,其匹配字符串结束的地方。 |
\b 与 \B |
不匹配任何字符,\b 表示单词的边界;\B 表示非单词边界的地方。 |
X? |
表示 X 可以出现 0 次或 1 次。 |
X+ |
表示 X 至少可以出现 1 次,即可以出现 1 次或多次。 |
X{n} |
表示 X 可以出现 n 次。 |
X{m,n} |
表示 X 至少出现 m 次,最多出现 n 次。 |
X{n,} |
表示 X 至少出现 n 次。 |
? |
该符号只能用在 ?、+、*、{m,n}、{n,} 的后边,用来修饰可以出现的次数按非贪婪模式进行匹配,即按照匹配模式进行最小限度的匹配。 |
| |
用来连接两个表达式,表示或的关系。例如 X\|Y 表示 X 或 Y 中的任意字符。 |
() |
将表达式的某个部分作为一个单元,即作一个分组,这样可以对该组整个进行操作。 |
\n (n 表示一个数字) |
有分组的情况下,表示对分组的引用。例如 \1 表示对分组 1 的引用。 |
\ |
该字符为转义字符,当一个符号自身有意义而又要表示这个字符的时候,需要在该字符前加一个转义字符 \ ,例如 \^ 表示 ^ ,\$ 表示 $ ,\\ 表示 \ 。需要用到转义字符表示的字符还有 ( 、) 、[ 、] 、{ 、} 、? 、+ 、* 、| 。 |
1、边界符
在进行匹配的时候,边界符不会匹配任何字符,只用于限定边界。
^
与$
分别表示的是字符串开始与结束的位置,若要求匹配的是整个字符串的内容,而不是字符串中的一部分,此时便可以使用^
与$
加以说明。例如,^a*$
表示的是由任意个a
组成的字符串,而a*
可以表示匹配整个字符串或其子串。\b
表示的是单词的边缘,在要求匹配的内容是整个单词,而不是单词的一部分时,\b
就派上用场了。例如,\bTom\b
对Tommy Tom
进行匹配,只会匹配后面的单词Tom
,而不会匹配Tommy
中的Tom
,而如果不使用\b
则两个都可以匹配。
2、匹配次数的贪婪与非贪婪
贪婪与非贪婪模式是针对量词而言的,其修饰符应该放在量词的后面。在匹配有重复字符或组出现的情况下,贪婪与非贪婪模式有不同的含义。
- 贪婪模式下在进行匹配时,将按照最大限度的可能性进行匹配。
- 非贪婪模式在匹配时,按照最小限度的可能性进行匹配。
例如,对于字符串 abbbabbba
,若使用正则式 a[\w]+a
进行匹配,则会按照贪婪模式进行匹配,匹配到的内容为 abbbabbba
,而使用正则式 a[\w]+?a
进行匹配,会以非贪婪模式进行匹配,匹配到的内容为 abbba
。
3、分组
实际应用中,有时需要重复出现的不是单个字符,而是特定的一组字符,例如要匹配由任意个 ab
组成的字符串,这时就需要使用分组。
()
为分组操作符,其功能为将特定的一组字符作为一个原子(不可分)的匹配单元来看待。例如,(ab)*
表示匹配由任意个ab
组成的字符串或子串。\n
(n
表示一个数字) 表示对分组的引用,当用于匹配的正则式中有很多分组时可以使用其对分组进行引用。例如,对于分组正则式((23)(45))
,其中包括三个分组2345
、23
、45
,编号分别为1
、2
、3
,((23)(45))\1
表示对23452345
匹配,((23)(45))\2
表示对234523
进行匹配。
4、示例
日期匹配 xxxx-xx-xx
:^\d{4}-(0[1-9]|1[0-2])-([0-2][1-9]|3[0-1])
二、String 正则处理方法
在 Java 中有四个内置的运行正则表达式的方法,分别是 matches()
、split()
、replaceFirst()
、replaceALL()
。注意 replace()
方法不支持正则表达式。
方法 | 描述 |
---|---|
s.matches("regex") |
当且仅当正则匹配整个字符串时返回 true |
s.split("regex") |
按匹配的正则表达式切片字符串 |
s.replaceFirst("regex", "replacement") |
替换首次匹配的字符串片段 |
s.replaceAll("regex", "replacement") |
替换所有匹配的字符 |
三、Java 正则匹配
Java 中使用正则表达式需要用到两个类,分别为 java.util.regex.Pattern
和 java.util.regex.Matcher
。
- 通过正则表达式创建模式对象
Pattern
。 - 通过模式对象
Pattern
,根据指定字符串创建匹配对象Matcher
。 - 通过匹配对象
Matcher
,根据正则表达式操作字符串。
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexTest {
public static void main(String[] args) {
String text = "Hello Regex!";
Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher(text);
// 遍例所有匹配的序列
while (matcher.find()) {
System.out.print("Start index: " + matcher.start());
System.out.print(" End index: " + matcher.end() + " ");
System.out.println(matcher.group());
}
// 创建第两个模式,将空格替换为 tab
Pattern replace = Pattern.compile("\\s+");
Matcher matcher2 = replace.matcher(text);
System.out.println(matcher2.replaceAll("\t"));
}
}
运行结果:
Start index: 0 End index: 5 Hello
Start index: 6 End index: 11 Regex
Hello Regex!
参考
- Bruce Eckel. Java 编程思想[M]. 机械工业出版社, 2007.
- 吴亚峰. JavaSE 6.0 编程指南[M]. 人民邮电出版社, 2007.
- Java 正则表达式详解