Java中Regex

來源:互聯網
上載者:User
Regex(Regular Expressions)可不是Java的專利,很多的語言像Perl,Python,PHP,Ruby等等都支援Regex,Regex是字串處理的利器,它是一種描述字串模式的式子,一個Regex的核心價值就是匹配一個字串。各個語言實現的Regex引擎並不完全相同,Oreilly出版的《精通Regex》是講解Regex的經典教程。這裡只是總結下Java中的Regex的相關知識,Java中的Regex功能是通過java.util.regex包中的兩個類來實現的:Pattern類,定義了封裝了Regex的對象;Matcher類,它定義了封裝了一個狀態機器的對象,這個狀態機器可以使用一個給定的Pattern對象搜尋一個特定的字串。這個包裡還定義了PatternSyntaxException類,如果編譯Regex建立Pattern對象時發現語法錯誤,將拋出異常。Regex也是個字串,一般會把它封裝到一個Pattern對象裡,某些簡單的情況下,完全可以不用regex包,只用String類的matches()就可以判斷該字串是否和Regex匹配。例如:

"one piece".matches("one.*");//true

使用java中的正則式基本上很簡單:

(1)把一個包含Regex的字串傳給Pattern類的靜態方法compile()來建立一個Pattern對象。

(2)然後通過調用Pattern對象的matcher()方法,並把要被搜尋的字串作為實參以獲得一個Matcher對象。

(3)調用Matcher對象的find()方法來搜尋字串。

(4)如果找到了這個模式串,可以查詢Matcher對象以找出該模式串在字串的什麼位置以及與其匹配的相關的其他資訊。

上面這4步是《Java2 入門經典》---Ivor Horton 這本書裡講的,這些步驟指引了我們怎麼來學Regex:1.最核心的東西就是Regex的編寫,也就是說掌握Regex文法來寫出想匹配的字串的模式,比如說要匹配一個email地址,怎麼來寫正則式。2. 弄明白matcher(),find(),compile()等方法的作用,其實就是查API,看這些方法參數是啥,傳回值是啥,作用是啥。3.關於Regex的編程都是按照某些步驟來做的,按要求步步為營即可。現在學習套路很明確了,簡單的說就是:掌握文法—>弄懂方法—>遵循步驟。

下面先說第一步,Java中Regex的文法,這裡就是理清文法的脈絡,具體的文法都是點到為止,因為baidu,維基等搜尋引擎就可以直接搜到關於正則式文法的詳細講解。Regex的文法要素有以下這些:常規字元,字元類(字元集合),萬用字元,量詞,邊界匹配符,運算子,組,標誌序列。結合例子來協助理清Regex文法的脈絡。

比如說有一個字串"0310handan",我們要寫一個正則式來描述這個字串,最簡單的怎麼做呢?就寫0310handan(查API會看到方法compile的參數是String regex,Regex是以字串的形式給出來的,但就其本身來說並不是字串,這裡為了突出Regex的文法特性,所以都不帶引號),這就是常規字元的用處,常規字元按其字面含義匹配。要都這麼乾的話這個Regex就是一一映射了,一個字串對應一個Regex,我們說Regex是描述字串的利器,這就意味著兩點:1.一個Regex能描述多個甚至是無限多個字串,這反映了它描述功能強大。2.一個字串可以被表示成多個Regex,這反映了它的靈活。因為既強大又靈活所以叫做“利器”。接下來的文法特性都是為達到這兩點來服務的。匹配的過程就是一個個的字元在匹配,比如說"0310handan",寫成Regex就是10個單元項,依次對應著0,3,1,0,h,a,n,d,a,n,加入什麼樣的文法特性可以讓正則式裡的一個單元項來匹配很多的字元呢,很自然的想法就是用一個單元項來表示很多存在某個共性的字元的集合,這個單元項叫做字元類,比如說[xyz]可以匹配x,y或者z,[^xyz]匹配x,y,z之外的任何字元,[a-z]匹配所有小寫字母,\d可以匹配數字0-9,等等。JavaRegexAPI提供了豐富的預定義字元類來表述這種想法,常用的有以下幾種,\d,\D,\w,\W,\s,\S。這幾個挺好記憶的,因為太常用了所以記法簡單,Java還提供了具有如下通用形式的大量的字元類,\p{name},name指定類的名稱,以下是幾個樣本:

\p{Lower} 包含小寫字母

\p{Upper} 包含大寫字母

\p{Punct} 包含所有的標點符號

不管記法怎樣,這些統統都表示一個單元項,用來匹配一個字元,還遺漏一個“大人物”,就是萬用字元,寫出來就是一個點號".",為啥說它是大人物呢,它能匹配所有字元。

到了這裡雖然長見識了,但是也有疑問了,表述能力是強了,不過寫起來還是很麻煩呀,以"0310handan"為例,還是要寫出來10個單元項,只是每個單元項有了多種可選擇的寫法而已,比如可以寫成...\d.....\p{Lower} ,但是寫出來的豈不是更長了,不由得感歎這Regex白學了,好麻煩。該介紹Regex中一個化繁為簡的文法特性了,就是量詞,具體地說分為貪婪量詞,脅迫量詞,佔有量詞。量詞用處很大並且使用簡單,它決定了一個單元項將匹配多少次,簡單的說可以把多個相同的單元項合并,所以上面的寫法也就是從文法上說能匹配"0310handan",實際中不可能這麼幹,因為要盡量把每個字元都表示成統一的形式,這樣再用個量詞就可以寫的簡潔些,比如說用這個式子來匹配該字串:\d\d\d\d\w\w\w\w\w\w,應用量詞後就可以寫成: \d+\w{6} 量詞如下所示:

+ 匹配1次或多次

* 匹配0次或多次

? 匹配0次或1次

這3個很常用,不過只要這仨的話夠用不?很明顯,這都沒有指定具體的量是多少,用{num}可以指定次數,比如說x{2}匹配"xx"。現在夠了麼,固定次數顯得不夠靈活,還要有指定最小次數和最大次數的{min,max},這裡不指定max也可以,例如x{2,}可以匹配"xx","xxx","xxxx",等等。量詞的種類現在似乎夠用了。其實還沒介紹完,到此為止談論的都是貪婪量詞,那麼脅迫量詞和佔有量詞是咋回事兒呢?後面再做解釋。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.