1.8正则表达式
正则表达式 (regular expression)用于指定字符串的模式,你可以在任何需要定位匹配某种特定模式的字符串的情况下使用正则表达式。
下面是一个简单的示例:
[Jj]ava.+
匹配下列形式的所有字符串:
l 第一个字母是J或j.
l 接下来的三个字母是ava
l 字符串的其余部分由一个或者多个任意的字符构成
例如 : 字符串“javanese”就匹配这个特定的正则表达式,但是字符串“core java”就不匹配 。
具体分类
l 字符类(character class)是一个括在括号中的可选择的字符集,例如:[Jj],[0-9],[A-Za-z]或[^0-9]。这里-表示是一个范围(所有的Unicode值落在两个边界范围之内的字符),而^表示补集(除了指定字符之外的所有字符)
l 有许多预定的字符类,例如/d(数字)和/p{Sc}(Unicode货币符号)。
表1-7正则表达式语法
语法 | 解释 |
字符 | |
c | C字符 |
/Unnnn,/Xnn,/0nn,/0nnn | 具有给定十六进制或十进制的码元 |
/t,/n,/r,/f,/a,/e | 控制符:制表符,换行符,回车符,换页符,警告符,逃逸符 |
/Cc | 与字符c相关的控制符 |
字符类 | |
[C1C2….] | 任何由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} | 一个命名字符类---请查看表1-8 |
/P{name} | 一个命名字符类的补集 |
一个边界匹配符 | |
^& | 输入的开头和结尾(或者在多行模式下行的开头和结尾) |
/b | 一个词语边界 |
/B | 一个非词语边界 |
/A | 输入的开头 |
/z | 输入的结尾 |
/Z | 除了行终止符之外的输入结尾 |
/G | 前一个匹配的结尾 |
量词 | |
X? | 可选的X |
X* | X, 0或多次 |
X+ | X,1或多次 |
X{n}X{n,}X{n,m} | Xn次,至少n次,在n到m次之间 |
量词后缀 | |
? | 将默认(贪婪)匹配转变为勉强匹配 |
+ | 将默认 (贪婪)匹配转变为占有匹配 |
集合操作 | |
XY | 任何X中的字符串,后面紧跟随任何Y中的字符串 |
X|Y | 任何X或Y的字符 |
群组 | |
(X) | 捕捉将X作为群组匹配的字符串 |
/n | 第n个群组的匹配 |
转义 | |
/c | 字符c(必须是不在字母表中的字符) |
/Q……………/E | 逐字地引用………….. |
(?.....) | 特殊结构------请查看Pattern类综中的API注释 |
表1-8预定义的字符类名字
字符类名字 | 解释 |
Lower | ASCII的小写字母[a-z] |
Upper | ASCII 的大写字母[A-Z] |
Alpha | ASCII 的字母[A-Za-z] |
Digit | ASCII的数字[0-9] |
Alnum | ASCII的字母或数字[A-Za-z0-9] |
XDigit | 十六进制数字[0-9A-Fa-f] |
Print或Graph | 可打印的ASCII字符[/x21-/x7E] |
Punct | ASCII的非字母和数字字符[/p{Print}&&/P{Alnum}] |
ASCII | 所有的ASCII字符[/x00-/x7F] |
Cntrl | ASCII控制字符[/x00-/x1F] |
Blank | 空格字符或制表符[/t] |
Space | 空白字符[/t/n/r/f/0x0B] |
javaLowerCase | 小写字母,正如Character.isLowerCase()确定的字符 |
javaUpperCase | 大写字母,正如Character.isUpperCase()确定的字符 |
javaWhiteSpace | 空白字符,正如Character.isWhitespace()确定的字符 |
javaMirrored | 镜像字符,正如 Character.isMirrored()确定的字符 |
InBlock | Block是Unicode字符块的名字,不过要剔除名字中的空格,例如BasicLatin和Mongolian。请查看 http://www.unicode.org已了解字符块名字列表 |
Category或InCategory | Category是Unicode字符类别的名字,例如,L(字母)和Sc(货币符号)。请查看http://www.unicode.org以了解字符类别名字列表 |
l 大部分字符都可以与它们自身匹配,例如在前面示例中的ava字符
l 符号可以匹配任何字符(有可能不包括行终止符,这取决于标志的设置)
l 使用 / 作为转义字符,例如, / . 匹配句号 而// 匹配反斜线。
l ^和&分别匹配一行的开头和结尾。
l 如果X和Y是正则表达式,那么XY表示“任何X的匹配后面跟随Y的匹配”,X|Y表示“任何X和Y的匹配”。
l 你可以将量词运用到表达式X:X+(1个或多个)、X*(0个或多个)与X?(0个或1个)。
l 默认情况下,量词要匹配能够使整个匹配成功的最大可能的重复次数。你可以修改这种行为,方法是使用后缀? (使用勉强或吝啬匹配,也就是匹配最小的重复次数)或使用后缀+(使用占有或贪婪匹配,也就是即使让这个匹配失败,也要匹配最大的重复次数)。 例如 ,字符串cab匹配[a-z]*ab ,但是不匹配[a-z]*+ab。 在第一种情况中,表达式[a-z]*匹配字符c,使得字符ab匹配模式的剩余部分 ;但是贪婪版本[a-z]*+将匹配字符串cab,模式的剩余部分将无法匹配。
l 我们使用群组来定义子表达式,其中群组用括号()括起来。例如,([+-]?) ([0-9]+)。然后你可以询问模式匹配器,让其返回每个组的匹配,也可以用/n来引用某个群组,其中n是群组号 (从/1开始)。 例如,下面一个有些复杂但是却可能很有用的正则表达式,它描述了十进制和十六进制整数:[+-]?[0-9]+|[Xx][0-9A-Fa-f]+
l
嵌套群组是按照前括号排序的,例如,假设我们有下面的模式
((1?[0-9] ): ([0-5][0-9]) ) [ap]m和下面的输出
11:59am
那么,匹配器会报告下面的群组:
群组索引 开始 结束 字符串
0 0 7 11:59am
1 0 5 11:59
2 0 2 11
3 3 5 59
以上是java核心技术第二卷中的正则表达式,运用很实用的也是群组这个概念,又兴趣请查相关资料分析,有什么经验大家一起交流。