正則表達式你們應該都不陌生,可是給人的印象可能就是不那麼高大上又很難理解、很難精通的這麼一個玩意兒,並且適用範圍又不是那麼寬。就是這麼一個感受有點雞肋的東西,若是到了須要的場合而不會用,就會面臨一種「前進是懸崖,後退是荒蕪」的困境。
我最近正在作一些關於Html代碼的解析工做,雖然手頭上有jsoup這樣好用的工具,仍是架不住世界上的技術人員代碼風格變幻無窮,不免遇到不按套路出牌的,專門花一點時間系統的學習一下正則表達式確實頗有必要。
這裏有同窗就要問了:網上不是有不少現成的例子麼,匹配適用的語言,直接拿過來用不就行了?固然,這樣作方便快捷,可是弊端也很明顯,一是缺少原理背後的講解,一旦找不到合適的例子就只能一籌莫展,這就是人們熟知的「魚」和「漁」,二是網上的博客什麼的也是人寫的,也不必定適合複雜多變的狀況,也不必定正確。因此,仍是決定深刻了解學習一下,寫下這篇專欄記錄學習經歷。
注:學習使用的教材是餘晟老師著《正則指引》(第二版),當前使用程序設計語言爲Java,在學習中可能更多關注與Java相關的內容。正則表達式
在一對方括號 [ 和 ] 之間列出全部可能出現的字符,包括可見以及不可見的字符;例如:[123]
表示能夠匹配一、二、3的單個字符。編程
若是能夠匹配的字符有規律性而且範圍比較大,好比0、一、二、三、四、五、六、七、八、9,表達式寫成 [0123456789]
這樣就顯得複雜也不美觀,因此引入符號「-」,使用 [x-y] 的形式表示在閉區間x到y範圍內的字符,上式能夠寫成[0-9]
編程語言
[0-9a-zA-Z]
工具
在表達式中有特殊功能而不做爲字符的一部分字符,稱爲元字符。好比前文講過的:[ ] - 都是元字符,若是想要恢復它們原本的字符屬性就要作一些特殊處理。先看通常狀況,取消元字符特殊含義的操做叫作轉義,操做是在表達式中的元字符前加反斜槓 。特殊狀況就是表示範圍的橫線 - ,當其緊鄰左方括號 [ 時就做爲普通字符處理,其餘狀況都做爲元字符表示範圍。學習
一、橫線 - 也支持反斜槓的轉義,即[0-9]表示0、-、9三個字符。
二、右方括號 ] 不須要轉義。編碼
當須要表示的字符組範圍很大,寫起來不方便,而恰巧它的補集(全集指全部字符)方便表示,引出了排除型字符組[^…]
,表示在當前位置匹配一個沒有列出的字符,請注意是「必須匹配一個沒有出現的字符」,而不是「不要匹配列出的字符」。例如:設計
[^0-9][^0-9]
能夠匹配「QQ」,但不能夠匹配「Q」。code
常見的字符組簡記法有\d
([0-9]
)、\w
([0-9a-zA-Z_]
)、\s
([\t\r\n\v\f]
)博客
`[0-9a-zA-Z]`能夠寫成`[\da-zA-Z]`
正則表達式也提供了上面三種經常使用簡記法的排除型:\D
、\W
、\S
,這三種分別對應各自的補集(全集是指全部字符,即[dD]能夠匹配任意字符,剩餘兩者同理)。程序設計
從新回顧1.3第一段話,當咱們所研究的問題要求咱們的全集不是全部字符,排除型字符組就顯得不是那麼的好用了。好比我須要匹配字母表第一、五、9個小寫字母,把全部字符看做全集顯然不合適,而把全部小寫字母看做全集就比較合適,可是寫成[b-df-hj-z]就比較複雜並且容易搞錯,Java就容許使用邏輯與(&&,也能夠理解爲取交集)來解決這個問題,即寫成:
[a-z]&&[^aei]
我所學習和說明的正則表達式是PCRE流派的,教材上還介紹了POSIX等其餘流派的正則表達式,這裏暫不做說明。
【預告】第二章量詞