======================================================
注:本文源代码点此下载
======================================================
正则表达式是jdk 1.4的新功能,但是对sed和awk这样的unix的标准实用工具,以及python,perl之类的语言来讲,它早就已经成为其不可或缺的组成部分了(有人甚至认为,它还是perl能大获成功的最主要的原因)。单从技术角度来讲,正则表达式只是一种处理字符串的工具(过去java这个任务是交由string,stringbuffer以及stringtokenizer处理的),但是它常常和i/o一起使用,所以放到这里来讲也不算太离题吧。[66]
正则表达式是一种功能强大但又非常灵活的文本处理工具。它能让你用编程的方式来描述复杂的文本模式,然后在字符串里把它找出来。一旦你找到了这种模式,你就能随心所欲地处理这些文本了。虽然初看起来正则表达式的语法有点让人望而生畏,但它提供了一种精练的动态语言,使我们能用一种通用的方式来解决各种字符串的问题,包括匹配,选择,编辑以及校验。
创建正则表达式
你可以从比较简单的东西入手学习正则表达式。要想全面地掌握怎样构建正则表达式,可以去看jdk文档的java.util.regex的pattern类的文档。
字符
b 字符b
\xhh 16进制值0xhh所表示的字符
\uhhhh 16进制值0xhhhh所表示的unicode字符
\t tab
\n 换行符
\r 回车符
\f 换页符
\e escape
正则表达式的强大体现在它能定义字符集(character class)。下面是一些最常见的字符集及其定义的方式,此外还有一些预定义的字符集:
字符集
.表示任意一个字符
[abc]表示字符a,b,c中的任意一个(与a|b|c相同)
[^abc]除a,b,c之外的任意一个字符(否定)
[a-za-z]从a到z或a到z当中的任意一个字符(范围)
[abc[hij]]a,b,c,h,i,j中的任意一个字符(与a|b|c|h|i|j相同)(并集)
[a-z&&[hij]]h,i,j中的一个(交集)
\s空格字符(空格键, tab, 换行, 换页, 回车)
\s非空格字符([^\s])
\d一个数字,也就是[0-9]
\d一个非数字的字符,也就是[^0-9]
\w一个单词字符(word character),即[a-za-z_0-9]
\w一个非单词的字符,[^\w]
如果你用过其它语言的正则表达式,那么你一眼就能看出反斜杠的与众不同。在其它语言里,"\\"的意思是"我只是要在正则表达式里插入一个反斜杠。没什么特别的意思。"但是在java里,"\\"的意思是"我要插入一个正则表达式的反斜杠,所以跟在它后面的那个字符的意思就变了。"举例来说,如果你想表示一个或更多的"单词字符",那么这个正则表达式就应该是"\\w+"。如果你要插入一个反斜杠,那就得用"\\\\"。不过像换行,跳格之类的还是只用一根反斜杠:"\n\t"。
这里只给你讲一个例子;你应该jdk文档的java.util.regex.pattern加到收藏夹里,这样就能很容易地找到各种正则表达式的模式了。
逻辑运算符
xy x 后面跟着 y
x|y x或y
(x) 一个"要匹配的组(capturing group)". 以后可以用\i来表示第i个被匹配的组。
边界匹配符
^一行的开始
$一行的结尾
\b一个单词的边界
\b一个非单词的边界
\g前一个匹配的结束
举一个具体一些的例子。下面这些正则表达式都是合法的,而且都能匹配"rudolph":
rudolph
[rr]udolph
[rr][aeiou][a-z]ol.*
r.*
数量表示符
"数量表示符(quantifier)"的作用是定义模式应该匹配多少个字符。
greedy(贪婪的): 除非另有表示,否则数量表示符都是greedy的。greedy的表达式会一直匹配下去,直到匹配不下去为止。(如果你发现表达式匹配的结果与预期的不符),很有可能是因为,你以为表达式会只匹配前面几个字符,而实际上它是greedy的,因此会一直匹配下去。
reluctant(勉强的): 用问号表示,它会匹配最少的字符。也称为lazy, minimal matching, non-greedy, 或ungreedy。
possessive(占有的): 目前只有java支持(其它语言都不支持)。它更加先进,所以你可能还不太会用。用正则表达式匹配字符串的时候会产生很多中间状态,(一般的匹配引擎会保存这种中间状态,)这样匹配失败的时候就能原路返回了。占有型的表达式不保存这种中间状态,因此也就不会回头重来了。它能防止正则表达式的失控,同时也能提高运行的效率。
greedyreluctantpossessive匹配
x?x??x?+匹配一个或零个x
x*x*?x*+匹配零或多个x
x+x+?x++匹配一个或多个x
x{n}x{n}?x{n}+匹配正好n个x
x{n,}x{n,}?x{n,}+匹配至少n个x
x{n,m}x{n,m}?x{n,m}+匹配至少n个,至多m个x
再提醒一下,要想让表达式照你的意思去运行,你应该用括号把'x'括起来。比方说:
abc+
似乎这个表达式能匹配一个或若干个'abc',但是如果你真的用它去匹配'abcabcabc'的话,实际上只会找到三个字符。因为这个表达式的意思是'ab'后边跟着一个或多个'c'。要想匹配一个或多个完整的'abc',你应该这样:
(abc)+
正则表达式能轻而易举地把你给耍了;这是一种建立在java之上的新语言。
charsequence
jdk 1.4定义了一个新的接口,叫charsequence。它提供了string和stringbuffer这两个类的字符序列的抽象:
interface charsequence {
charat(int i);
length();
subsequence(int start, int end);
tostring();
}
为了实现这个新的charsequence接口,string,stringbuffer以及charbuffer都作了修改。很多正则表达式的操作都要拿charsequence作参数。
pattern和matcher
先给一个例子。下面这段程序可以测试正则表达式是否匹配字符串。第一个参数是要匹配的字符串,后面是正则表达式。正则表达式可以有多个。在unix/linux环境下,命令行下的正则表达式还必须用引号。
当你创建正则表达式时,可以用这个程序来判断它是不是会按照你的要求工作。
//: c12:testregularexpression.java
// allows you to easly try out regular expressions.
// {args: abcabcabcdefabc "abc+" "(abc)+" "(abc){2,}" }
import java.util.regex.*;
public class testregularexpression {
public static void main(string[] args) {
if(args.length 关注我收藏该文与我联系
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/