如果你曾經用過Perl或任何其他內建正則表達式支持的語言
你一定知道用正則表達式處理文本和匹配模式是多麼簡單
如果你不熟悉這個術語
那麼
正則表達式
(Regular Expression)就是一個字符構成的串
它定義了一個用來搜索匹配字符串的模式
許多語言
包括Perl
PHP
Python
javascript和JScript
都支持用正則表達式處理文本
一些文本編輯器用正則表達式實現高級
搜索
替換
功能
那麼Java又怎樣呢?本文寫作時
一個包含了用正則表達式進行文本處理的Java規范需求(Specification Request)已經得到認可
你可以期待在JDK的下一版本中看到它
然而
如果現在就需要使用正則表達式
又該怎麼辦呢?你可以從下載源代碼開放的Jakarta
ORO庫
本文接下來的內容先簡要地介紹正則表達式的入門知識
然後以Jakarta
ORO API為例介紹如何使用正則表達式
一
正則表達式基礎知識
我們先從簡單的開始
假設你要搜索一個包含字符
cat
的字符串
搜索用的正則表達式就是
cat
如果搜索對大小寫不敏感
單詞
catalog
Catherine
sophisticated
都可以匹配
也就是
句點符號
假設你在玩英文拼字游戲
想要找出三個字母的單詞
而且這些單詞必須以
t
字母開頭
以
n
字母結束
另外
假設有一本英文字典
你可以用正則表達式搜索它的全部內容
要構造出這個正則表達式
你可以使用一個通配符——句點符號
這樣
完整的表達式就是
t
n
它匹配
tan
ten
tin
和
ton
還匹配
t#n
tpn
甚至
t n
還有其他許多無意義的組合
這是因為句點符號匹配所有字符
包括空格
Tab字符甚至換行符
方括號符號
為了解決句點符號匹配范圍過於廣泛這一問題
你可以在方括號(
[]
)裡面指定看來有意義的字符
此時
只有方括號裡面指定的字符才參與匹配
也就是說
正則表達式
t[aeio]n
只匹配
tan
Ten
tin
和
ton
但
Toon
不匹配
因為在方括號之內你只能匹配單個字符
或
符號
如果除了上面匹配的所有單詞之外
你還想要匹配
toon
那麼
你可以使用
|
操作符
|
操作符的基本意義就是
或
運算
要匹配
toon
使用
t(a|e|i|o|oo)n
正則表達式
這裡不能使用方擴號
因為方括號只允許匹配單個字符
這裡必須使用圓括號
()
圓括號還可以用來分組
具體請參見後面介紹
表示匹配次數的符號
表一顯示了表示匹配次數的符號
這些符號用來確定緊靠該符號左邊的符號出現的次數
假設我們要在文本文件中搜索美國的社會安全號碼
這個號碼的格式是
用來匹配它的正則表達式如圖一所示
在正則表達式中
連字符(
)有著特殊的意義
它表示一個范圍
比如從
到
因此
匹配社會安全號碼中的連字符號時
它的前面要加上一個轉義字符
\
圖一
匹配所有
形式的社會安全號碼
假設進行搜索的時候
你希望連字符號可以出現
也可以不出現——即
和
都屬於正確的格式
這時
你可以在連字符號後面加上
?
數量限定符號
如圖二所示
圖二
匹配所有
和
形式的社會安全號碼
下面我們再來看另外一個例子
美國汽車牌照的一種格式是四個數字加上二個字母
它的正則表達式前面是數字部分
[
]{
}
再加上字母部分
[A
Z]{
}
圖三顯示了完整的正則表達式
圖三
匹配典型的美國汽車牌照號碼
如
KV
否
符號
^
符號稱為
否
符號
如果用在方括號內
^
表示不想要匹配的字符
例如
圖四的正則表達式匹配所有單詞
但以
X
字母開頭的單詞除外
圖四
匹配所有單詞
但
X
開頭的除外
圓括號和空白符號
假設要從格式為
June
的生日日期中提取出月份部分
用來匹配該日期的正則表達
圖五
匹配所有Moth DD
YYYY格式的日期
新出現的
\s
符號是空白符號
匹配所有的空白字符
包括Tab字符
如果字符串正確匹配
接下來如何提取出月份部分呢?只需在月份周圍加上一個圓括號創建一個組
然後用ORO API(本文後面詳細討論)提取出它的值
修改後的正則表達式如圖六所示
圖六
匹配所有Month DD
YYYY格式的日期
定義月份值為第一個組
其它符號
為簡便起見
你可以使用一些為常見正則表達式創建的快捷符號
如表二所示
表二
常用符號
例如
在前面社會安全號碼的例子中
所有出現
[
]
的地方我們都可以使用
\d
修改後的正則表達式如圖七所示
圖七
匹配所有
格式的社會安全號碼
二
Jakarta
ORO庫
有許多源代碼開放的正則表達式庫可供Java程序員使用
而且它們中的許多支持Perl
兼容的正則表達式語法
我在這裡選用的是Jakarta
ORO正則表達式庫
它是最全面的正則表達式API之一
而且它與Perl
正則表達式完全兼容
另外
它也是優化得最好的API之一
Jakarta
ORO庫以前叫做OROMatcher
Daniel Savarese大方地把它贈送給了Jakarta Project
你可以按照本文最後參考資源的說明下載它
我首先將簡要介紹使用Jakarta
ORO庫時你必須創建和訪問的對象
然後介紹如何使用Jakarta
ORO API
▲ PatternCompiler對象
首先
創建一個Perl
Compiler類的實例
並把它賦值給PatternCompiler接口對象
Perl
Compiler是PatternCompiler接口的一個實現
允許你把正則表達式編譯成用來匹配的Pattern對象
▲ Pattern對象
要把正則表達式編譯成Pattern對象
調用compiler對象的compile()方法
並在調用參數中指定正則表達式
例如
你可以按照下面這種方式編譯正則表達式
t[aeio]n
默認情況下
編譯器創建一個大小寫敏感的模式(pattern)
因此
上面代碼編譯得到的模式只匹配
tin
tan
ten
和
ton
但不匹配
Tin
和
taN
要創建一個大小寫不敏感的模式
你應該在調用編譯器的時候指定一個額外的參數
創建好Pattern對象之後
你就可以通過PatternMatcher類用該Pattern對象進行模式匹配
▲ PatternMatcher對象
PatternMatcher對象根據Pattern對象和字符串進行匹配檢查
你要實例化一個Perl
Matcher類並把結果賦值給PatternMatcher接口
Perl
Matcher類是PatternMatcher接口的一個實現
它根據Perl
正則表達式語法進行模式匹配
使用PatternMatcher對象
你可以用多個方法進行匹配操作
這些方法的第一個參數都是需要根據正則表達式進行匹配的字符串
·boolean matches(String input
Pattern pattern)
當輸入字符串和正則表達式要精確匹配時使用
換句話說
正則表達式必須完整地描述輸入字符串
·boolean matchesPrefix(String input
Pattern pattern)
當正則表達式匹配輸入字符串起始部分時使用
·boolean contains(String input
Pattern pattern)
當正則表達式要匹配輸入字符串的一部分時使用(即
它必須是一個子串)
另外
在上面三個方法調用中
你還可以用PatternMatcherInput對象作為參數替代String對象
這時
你可以從字符串中最後一次匹配的位置開始繼續進行匹配
當字符串可能有多個子串匹配給定的正則表達式時
用PatternMatcherInput對象作為參數就很有用了
用PatternMatcherInput對象作為參數替代String時
上述三個方法的語法如下
·boolean matches(PatternMatcherInput input
Pattern pattern)
·boolean matchesPrefix(PatternMatcherInput input
Pattern pattern)
·boolean contains(PatternMatcherInput input
Pattern pattern)
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25544.html