【php精品源码栏目提醒】:网学会员为广大网友收集整理了,【精品】Java正则表达式详解 - 其它资料,希望对大家有所帮助!
Java 正则表达式详解(转)2008-09-18 16:34 如果你曾经用过 Perl 或任何其他内建正则表达式支持的语言,你一定知道用正则表达式处理文本和匹配模式是多么简单。
如果你不熟悉这个术语,那么“正则表达式”(Regular Expression)就是一个字符构成的串,它定义了一个用来搜索匹配字符串的模式。
许多语言,包括 Perl、
PHP、Python、JavaScript 和 JScript,都支持用正则表达式处理文本,一些文本编辑器用正则表达式实现高级“搜索-替换”功能。
那么 Java 又怎样呢?本文写作时,一个包含了用正则表达式进行文本处理的 Java 规范需求(Specification Request)已经得到认可,你可以期待在 JDK 的下一版本中看到它。
然而,如果现在就需要使用正则表达式,又该怎么办呢?你可以从 Apache.org 下载源代码开放的 Jakarta-ORO 库。
本文接下来的内容先简要地介绍正则表达式的入门知识,然后以 Jakarta-ORO API为例介绍如何使用正则表达式。
一、正则表达式基础知识 我们先从简单的开始。
假设你要搜索一个包含字符“cat”的字符串,搜索用的正则表达式就是“cat”。
如果搜索对大小写不敏感,单词“catalog”、“Catherine”、“sophisticated”都可以匹配。
也就是说:1.1 句点符号 假设你在玩英文拼字游戏, 而 想要找出三个字母的单词, 且这些单词必须以“t”字母开头,以“n”字母结束。
另外,假设有一本英文字典,你可以用正则表达式搜索它的全部内容。
要构造出这个正则表达式,你可以使用一个通配符——句点符号“.”。
这样,完整的表达式就是“t.n”,它匹配“tan”、“ten”、“tin”和“ton”,还匹配“tn”、“tpn”甚至“t n”,还有其他许多无意义的组合。
这是因为句点符号匹配所有字符,包括空格、Tab 字符甚至换行符:1.2 方括号符号 为了解决句点符号匹配范围过于广泛这一问题,你可以在方括号(“”)里面指定看来有意义的字符。
此时,只有方括号里面指定的字符才参与匹配。
也就是说,正则表达式“taeion”只匹配“tan”、“Ten”、“tin”和“ton”。
但“Toon”不匹配,因为在方括号之内你只能匹配单个字符:1.3 “或”符号 如果除了上面匹配的所有单词之外,你还想要匹配“toon”,那么,你可以使用“”操作符。
“”操作符的基本意义就是“或”运算。
要匹配“toon”,使用 “taeiooon”正则表达式。
这里不能使用方扩号,因为方括号只允许匹配单个字符;这里必须使用圆括号“”。
圆括号还可以用来分组,具体请参见后面介绍。
1.4 表示匹配次数的符号 表一显示了表示匹配次数的符号,这些符号用来确定紧靠该符号左边的符号出现的次数:假设我们要在文本文件中搜索美国的社会安全号码。
这个号码的格式是999-99-9999。
用来匹配它的正则表达式如图一所示。
在正则表达式中,连字符(“-”)有着特殊的意义,它表示一个范围,比如从0到9。
因此,匹配社会安全号码中的连字符号时,它的前面要加上一个转义字符“”。
图一:匹配所有123-12-1234形式的社会安全号码假设进行搜索的时候,你希望连字符号可以出现,也可以不出现——即,999-99-9999和999999999都属于正确的格式。
这时,你可以在连字符号后面加上“?”数量限定符号,如图二所示: 图二:匹配所有123-12-1234和123121234形式的社会安全号码下面我们再来看另外一个例子。
美国汽车牌照的一种格式是四个数字加上二个字母。
它的正则表达式前面是数字部分“0-94”,再加上字母部分“A-Z2”。
图三显示了完整的正则表达式。
图三:匹配典型的美国汽车牌照号码,如8836KV1.5 “否”符号“”符号称为“否”符号。
如果用在方括号内, “”表示不想要匹配的字符。
例如,图四的正则表达式匹配所有单词,但以“X”字母开头的单词除外。
图四:匹配所有单词,但“X”开头的除外1.6 圆括号和空白符号 假设要从格式为“June 26 1951”的生日日期中提取出月份部分,用来匹配该日期的正则表达式可以如图五所示: 图五:匹配所有 Moth DDYYYY 格式的日期新出现的“s”符号是空白符号,匹配所有的空白字符,包括 Tab 字符。
如果字符串正确匹配,接下来如何提取出月份部分呢?只需在月份周围加上一个圆括号创建一个组, ( 然后用 ORO API 本文后面详细讨论)提取出它的值。
修改后的正则表达式如图六所示: 图六:匹配所有 Month DDYYYY 格式的日期,定义月份值为第一个组1.7 其它符号 为简便起见,你可以使用一些为常见正则表达式创建的快捷符号。
如表二所示: 表二:常用符号例如,在前面社会安全号码的例子中,所有出现“0-9”的地方我们都可以使用“d”。
修改后的正则表达式如图七所示: 图七:匹配所有123-12-1234格式的社会安全号码字符B 字符 Bxhh 16进制值0xhh 所表示的字符uhhhh 16进制值0xhhhh 所表示的 Unicode 字符t Tabn 换行符r 回车符f 换页符e Escape正则表达式的强大体现在它能定义字符集character class。
下面是一些最常见的字符集及其定义的方式,此外还有一些预定义的字符集:字符集. 表示任意一个字符abc 表示字符 a,b,c 中的任意一个与 abc 相同abc 除 a,b,c 之外的任意一个字符否定a-zA-Z 从 a 到 z 或 A 到 Z 当中的任意一个字符范围abchij abchij 中的任意一个字符与 abchij 相同并集a-zhij hij 中的一个交集s 空格字符空格键 tab 换行 换页 回车S 非空格字符sd 一个数字,也就是0-9D 一个非数字的字符,也就是0-9w 一个单词字符word character,即a-zA-Z_0-9W 一个非单词的字符,w在一些语言里,的意思是只是要在正则表达式里插入一个反斜杠。
没什么特别的意思。
但是在 Java 里,的意思是要插入一个正则表达式的反斜杠,所以跟在它后面的那个字符的意思就变了。
举例来说,如果想表示一个或更多的单词字符,那么这个正则表达式就应该是w。
如果要插入一个反斜杠,那就得用。
不过像换行,跳格之类的还是只用一根反斜杠:nt。
逻辑运算符XY X 后面跟着 YXY X或Y 一个要匹配的组capturing group. 以后可以用i 来表示第 i 个被匹X 配的组。
边界匹配符 一行的开始 一行的结尾b 一个单词的边界 B 一个非单词的边界 G 前一个匹配的结束匹配的模式Pattern flagscompile 方法还有一个版本,它需要一个控制正则表达式的匹配行为的参数:Pattern Pattern.compileString regex int flagflag 的取值范围如下:Pattern.CANON_EQ当且仅当两个字符的正规分解canonical decomposition都完全相同的情况下,才认定匹配。
比如用了这个标志之后,表达式au030A会匹配。
默认情况下,不考虑规范相等性canonical equivalence。
Pattern.CASE_INSENSITIVEi默认情况下,大小写不明感的匹配只适用于 US-ASCII 字符集。
这个标志能让表达式忽略大小写进行匹配。
要想对 Unicode 字符进行大小不明感的匹配,只要将 UNICODE_CASE 与这个标志合起来就行了。
Pattern.COMMENTSx 在这种模式下,匹配时会忽略正则表达式里的空格字符注:不是指表达式里的s,而是指表达式里的空格,tab,回车之类。
注释从开始,一直到这行结束。
可以通过嵌入式的标志来启用 Unix 行模式。
Pattern.DOTALLs 在这种模式下,表达式.可以匹配任意字符,包括表示一行的结束符。
默认情况下,表达式.不匹配行的结束符。
Pattern.MULTILINEm 在这种模式下,和分别匹配一行的开始和结束。
此外,仍然匹配字符串的开始,也匹配字符串的结束。
默认情况下,这两个表达式仅仅匹配字符串的开始和结束。
Pattern.UNICODE_CASEu 在这个模式下,如果你还启用了 CASE_INSENSITIVE 标志,那么它会对 Unicode 字符进行大小写不明感的匹配。
默认情况下,大小写不明感的匹配只适用于 US-ASCII 字符集。
Pattern.UNIX_LINESd 在这个模式下,只有n才被认作一行的中止,并且与.,,以及进行匹配。
在 这 些 标 志 里 面 , Pattern.CASE_INSENSITIVE ,Pattern.MULTILINE , 以 及 Pattern.COMMENTS 是 最 有 用 的 其 中Pattern.COMMENTS 还能帮我们把思路理清楚,并且/或者做文档。
注意,你可以用在表达式里插记号的方式来启用绝大多数的模式。
这些记号就在上面那张表的各个标志的下面。
你希望模式从哪里开始启动,就在哪里插记号。