如何使用正規表示法-3

在如何使用正規表示法-2當中, 討論了如何使用特殊字元,
現在要來討論, 如何抓到重複或型態相同的字元,

舉個例子來說
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>


如果你想抓出src的位址, 你會怎麼做?
先來理解下面的東西
連續符號

字元?: 字元後面接一個?號, 代表著該字元出現0次或1次
字元*: 字元後面接一個*號, 代表著該字元出現0次或1次以上
字元+: 字元後面接一個+號, 代表著該字元至少出現1次以上
字元{n} : 字元後面接{n,}號, 代表著該字元出現n次
字元{n,} : 字元後面接{n,}號, 代表著該字元出現n次以上
字元{n,m} : 字元後面接{n,}號, 代表著該字元至少出現n次, 但是最多出現m次


如果你想要辨認出手機電話號碼,
我們知道台灣手機號碼都是09開頭,
所以用括弧包起來, 並且加上+號,
表示最少要出現一次,
而後面接8個號碼, 由於不知道會怎麼排列, 只知道範圍是0-9,
因此我們就利用[0-9]找出八個號碼並且用{8}來限制是8位數,
整個表示式長這樣 "(09)+[0-9]{8}"或"(09)+[\\d]{8}"
String str = "0987654321";
Pattern pattern = Pattern.compile("(09)+[\\d]{8}");
Matcher matcher = pattern.matcher(str);
while(matcher.find()) {
    System.out.print(matcher.group());
}
結果就會印出0987654321

而不管你的字串是長 abc0987654321 或者 1230987654321 或者 1110987654321222
甚至abc1230987654321321bca。

表示式都只會找出0987654321。

再來多幾個例子, 例如驗證E-mail格式, 電子郵件格式如下,
用戶名@網域名稱
通常用戶名開頭都會是文字, 因此我們可以設定^[0-9a-z_-]+,
這段表示至少會有一個用文字或數字或底線的開頭,
且文字長度不限制,
再來可能會多一個([.][0-9a-z_-]+)*,
這段表示式的意思是指, 如果有後面這串文字的話, 則一定會多出一個.xxx+,
而且不一定只出現一次, 可能出現無限多次,
再來就是@這個符號,
接著我們設定網域名稱,
一樣開頭會出現[0-9a-z_-]+至少一次的文字, 長度不限制,
接著會出現([.][0-9a-z_-]+)*$這樣的結尾,

所以整段表示式長這樣
"^[0-9a-z_-]+([.][0-9a-z_-]+)*@[0-9a-z_-]+([.][0-9a-z_-]+)*$"
String str = "givemepass@gmail.com";
Pattern pattern = 
    Pattern.compile("^[_a-z0-9-]+([._a-z0-9-]+)*@[a-z0-9-]+([.a-z0-9-]+)*$");
Matcher matcher = pattern.matcher(str);
while(matcher.find()) {
    System.out.print(matcher.group());
}
什麼意思呢?
舉個例子
givemepass@gmail.com 用到
符合 "^[0-9a-z_-]+@[0-9a-z_-]+([.0-9a-z_-]+)*$"
give.me.pass@gmail.com.tw 用到
符合 "^[0-9a-z_-]+([.0-9a-z_-]+)*@[0-9a-z_-]+([.0-9a-z_-]+)*([.0-9a-z_-]+)*$"
give-me.pass@gmail 用到
符合 "^[0-9a-z_-]+([.0-9a-z_-]+)*@[0-9a-z_-]+"
由此可知, 我們的表示式涵蓋所有可能的格式。

那麼現在回到文章開頭的那個例子,
文字長這樣, 如果要抓出src後面的內容, 我們該怎麼做呢?

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>

其實不難, 分析網址的格式,
(http://)(ajax)(.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js)
我們將這個分成三部分,
第一個部分是http://
第二部分接著都是由數字或文字所組成的   [a-z0-9]+
最後一部分就是多了斜線跟點, 因此是    ([/.a-z0-9]+)*
所以表示式就是"(http://)[a-z0-9]+([/.a-z0-9]+)*
String str = 
    "<script type=\"text/javascript\" "+
    "src=\"http://ajax.googleapis.com/"+
    "ajax/libs/jquery/1.7.1/jquery.min.js\"></script>";
Pattern pattern = Pattern.compile("(http://)[a-z0-9]+([/.a-z0-9]+)*");
Matcher matcher = pattern.matcher(str);
while(matcher.find()) {
    System.out.print(matcher.group());
}
出來的結果就會是http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js

如果你想要擷取中文的話怎麼辦呢?
以下網址提供相當不錯的解法
http://ycfunet.blogspot.com/2007/03/regular-expressionunicode.html
String str = 
    "我是一串中文字,YA";
Pattern pattern = Pattern.compile("\\p{InCJKUnifiedIdeographs}");
Matcher matcher = pattern.matcher(str);
while(matcher.find()) {
    System.out.print(matcher.group());
}
結果會印出  我是一串中文字