笔记:正则表达式
正则表达式(regular expression)用于指定字符串的模式,可以在任何需要定位匹配某种特定模式的字符串的情况下使用正则表达式,正则表达式的语法如下:
语法 | 解释 |
字符 |
|
c | 表示字符 c |
\unnnn,\xnn,\0n,\0nn,\0nnn | 具有给定十六进制或者十进制值的码元 |
\t,\n,\r,\f,\a | 控制符:制表符、换行符、回车符、换页符、警告符 |
字符类 |
|
[C1,C2,…] | 任何由C1、C2,…表示的字符,其中C1可以表示多个字符,字符范围C1-C2或者字符类 |
[^…] | 排除匹配,^之后的字符不能匹配 |
[… && …] | 二个字符集的交集 |
预定义字符类 |
|
. | 除了行终止符之外的所有字符(在 DOTALL 标志被设置时,则表示所有字符) |
\d | 一个数字,等价 [0-9] |
\D | 一个非数字,等价[^0-9] |
\s | 一个空白字符[\t\n\r\f\x0B] |
\S | 一个非空白字符 |
\w | 一个词语字符[a-zA-Z0-9_] |
\W | 一个非词语字符 |
\p{name} | 一个命名字符类,命名字符参考命名字符表 |
\P{name} | 一个命名字符类的补集 |
边界匹配符 |
|
^ $ | 表示输入的开头和结尾(或者在多行模式下行的开头和结尾) |
\b | 一个词语边界 |
\B | 一个非词语边界 |
\A | 输入的开头 |
\z | 输入的结尾 |
\Z | 除了行终止符之外的输入结尾 |
\G | 前一个匹配的结尾 |
量词 |
|
X? | 可选的X |
X* | X重复0次或多次 |
X+ | X重复1次或多次 |
X{n} X{n,} X{n,m} | X重复n次,至少n次,在n到m次之间 |
量词后缀 |
|
? | 在默认(贪婪)匹配转变为勉强匹配 |
+ | 在默认(贪婪)匹配转变为占用匹配 |
集合操作 |
|
XY | 在任何X中的字符串,后面跟随任何Y中的字符串 |
X|Y | 任何X或Y中的字符串 |
群组 |
|
(X) | 将X做为群组 |
\n | 第 n 个群组的匹配 |
匹配标志:
- CASE_INSENSITIVE:匹配字符时不区分字母的大小写,默认情况下,这个标志只考虑US ASCII 字符
- UNICODE_CASE:当与CASE_INSENSITIVE组合时,用Unicode字母的大小写来匹配
- MULTILINE:^ 和 $ 匹配行的开头和结尾,而不是整个输入的开头和结尾
- UNIX_LINUX:在多行模式中匹配 ^ 和 $ 时,只有 '\n' 被识别成行终止符
- DOTALL:当使用整个标志时,. 符号匹配所有字符,包含行终止符
常用方法说明:
- matches() 方法不能用于查找正则表达式多次出现。如果需要,请使用find(), start() 和 end() 方法。
- lookingAt() 与matches() 方法类似,最大的不同是,lookingAt()方法对文本的开头匹配正则表达式;而
matches() 对整个文本匹配正则表达式。换句话说,如果正则表达式匹配文本开头而不匹配整个文本,lookingAt() 返回true,而matches() 返回false
- find() 方法用于在文本中查找出现的正则表达式,文本是创建Matcher时,通过 Pattern.matcher(text) 方法传入的。如果在文本中多次匹配,find() 方法返回第一个,之后每次调用 find() 都会返回下一个。
- start() 和 end() 返回每次匹配的字串在整个文本中的开始和结束位置。实际上, end() 返回的是字符串末尾的后一位,这样,可以在把 start() 和 end() 的返回值直接用在String.substring() 里
- group() 方法假设想在一个文本中查找URL链接,并且想把找到的链接提取出来。当然可以通过 start()和 end()方法完成。但是用group()方法更容易些
- group(int groupNo) 方法访问一个分组。一个正则表达式可以有多个分组。每个分组由一对括号标记。想要访问正则表达式中某分组匹配的文本,可以把分组编号传入 group(int groupNo)方法。group(0) 表示整个正则表达式,要获得一个有括号标记的分组,分组编号应该从1开始计算
示例代码:
- 字符串匹配:
Pattern pattern = Pattern.compile("^[a-zA-Z0-9]+$");
String testString = "sdlfkjsdkfj342349898LKJKJ";
Matcher matcher = pattern.matcher(testString);
System.out.println("testString=" + testString + " pattern=" + pattern.pattern() + " matcher " + matcher.matches());
System.out.println("-----------------------------------------------------------");
- 排除匹配:
pattern = Pattern.compile("[^89]+");
testString = "1234567890";
matcher = pattern.matcher(testString);
System.out.println("testString=" + testString + " pattern=" + pattern.pattern() + " matcher " + matcher.matches());
testString = "1234567";
matcher = pattern.matcher(testString);
System.out.println("testString=" + testString + " pattern=" + pattern.pattern() + " matcher " + matcher.matches()
+" string "+ matcher.group());
System.out.println("-----------------------------------------------------------");
- 群组匹配:
pattern = Pattern.compile("([a-zA-Z0-9]+):([0-9]+)");
testString = "a000001:330,a0000002:440,a0000004:445";
matcher = pattern.matcher(testString);
while (matcher.find()) {
System.out.println("group 0 value " + matcher.group(0) + " start " + matcher.start(0) + " end " + matcher.end(0));
System.out.println("group 1 value " + matcher.group(1) + " start " + matcher.start(1) + " end " + matcher.end(1));
System.out.println("group 2 value " + matcher.group(2) + " start " + matcher.start(2) + " end " + matcher.end(2));
System.out.println("-----------------------------------------------------------");
}
- 匹配替换字符串:
pattern = Pattern.compile("[ab]+");
testString = "abcdefghijkmul";
matcher = pattern.matcher(testString);
String output = matcher.replaceAll("8");
System.out.println("pattern " + pattern.pattern() + " input string " + testString + " replace " + output);
output = matcher.replaceAll(Matcher.quoteReplacement("$"));
System.out.println("pattern " + pattern.pattern() + " input string " + testString + " replace " + output);
output = matcher.replaceAll("\\$");
System.out.println("pattern " + pattern.pattern() + " input string " + testString + " replace " + output);
System.out.println("-----------------------------------------------------------");
- 匹配分隔字符串:
pattern = Pattern.compile(",");
testString = "a000001:330,a0000002:440,a0000004:445";
String[] tokens = pattern.split(testString);
for (int i = 0; i < tokens.length; i++) {
System.out.println("pattern " + pattern.pattern() + " testString " + testString + " split " + tokens[i]);
}
System.out.println("-----------------------------------------------------------");