正則表達式-基本概念與簡單元字符

正則表達式工做中一直在使用,可是沒有系統的總結過,今天就從小白的角度梳理一下正則表達式的使用,主要關注的是正則的思想java

邊寫邊聽五月天的派對動物。學會了正則省下的時間就能夠去party了 ^_^node

正則表達式概念

咱們先來看看正則表達式的概念,畢竟正則的語法、使用都是圍繞着它要解決的問題來的。正則表達式

wikipedia定義:編程

正則表達式(英語:Regular Expression,在代碼中常簡寫爲regex、regexp或RE),
又稱正規表示式、正規表示法、正規表達式、規則表達式、常規表示法,
是計算機科學的一個概念。正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。
在不少文本編輯器裏,正則表達式一般被用來檢索、替換那些匹配某個模式的文本。

首先,正則表達式是一個字符串組成的模式,用來匹配一個字符串,通常用在檢索,替換裏,也常常用來校驗一些字符模式,檢驗是否匹配一個給定的規則。編程語言

正則表達式的基本語法

正則表達式使用字符串來描述字符串,也就是說跟編程語言,正則表達式是有本身的關鍵字的,學會這些關鍵字是咱們入門正則的第一步,而後在使用中領會正則表達式的思想,一步步進階。編輯器

首先要明確一點,正則引擎在匹配時是一個字符一個字符的匹配的,跟咱們日常印象中一串一串匹配的思惟是不一樣的,這個須要咱們時刻牢記。工具

匹配單個字符的元字符

咱們首先來看一下匹配一個字符的關鍵字:日誌

元字符 名稱 含義
. 點號 匹配任意一個字符
[……] 字符組 匹配組內的單個字符
[^……] 排除性字符組 匹配單個未列出的字符
\meta 轉義字符 特殊含義或轉義元字符

英文點號能夠匹配任意字符,可是不包括換行符,也就是說匹配到換行點號就匹配失敗了,咱們可使用\n來匹配換行符,在java中也有MULTI_LINES來指定讓點號匹配到換行符code

若是咱們想匹配一個文本形式的點號怎麼弄呢,可使用反斜線\來轉義關鍵字,這樣就能夠匹配一個點號,而不是匹配任意字符的關鍵字點號了。regexp

關於字符組須要說明一點,可使用-來描述一個範圍,好比咱們想匹配數字,咱們能夠寫一個全列[0123456789],也可使用[0-9],字符也是同樣[a-zA-z]匹配英文大小寫的26個字母,若是咱們想匹配橫槓怎麼辦呢?只有一個辦法,那就是把它寫在緊跟左中括號後面,[-a-z]匹配橫槓和a-z的全部字母,若是寫在中間是會被當成關鍵字來解析的。

計數元字符

有了匹配單個字符的關鍵字,匹配多個就要用到計數元字符,經常使用的有下面這些:

元字符 名稱 含義 區間表示
? 問號 匹配至多一次 {0,1} greedy的
* 星號 匹配任意屢次,也能夠不匹配 {0,}
+ 加號 匹配至少一次 {1,}
{min, max} 區間 min <=匹配次數 <= max grep默認不支持{元字符,可使用-E選項
*?,+?,??,{min,max}? 忽略優先量詞 匹配儘量少的內容
*+, ++, ?+ {min,max}+ 佔有優先量詞 匹配內容後不會交還,相似固化分組

?*+這三個元字符是可使用{}來模擬的,不過在一些正則流派裏不支持{}元字符,咱們只能使用這三個。

在爲加?的量詞上,前四個都是貪婪匹配的,也就是說他們會匹配儘量多的字符,在匹配失敗的時候纔會中止,這有時候頗有用,但有時候會讓咱們沒有通過深思寫出來的正則匹配到錯誤的內容。第四列在量詞後面加了?則正相反,它會匹配儘量少的內容,是先爲人後爲幾的,這兩種方式的區別咱們後面再講,這跟表達式引擎的遞歸與回溯有關。

最後一列是佔有優先量詞,這個概念是在貪婪的基礎上加了鐵公雞屬性(佔有),也就是說經它匹配過的字符就是它的了,不會再吐出來。後面咱們在講回溯跟固化分組時是再來回顧這個佔有優先量詞。

簡寫

上面二者組合能夠匹配大部分字符了,不過有些寫起來很繁瑣,所以正則爲咱們提早定義好了一些簡寫,使用時能夠減小表達式長度。

元字符 名稱 含義
\s [ \f\v\t\n\r] 匹配空格,製表符,回車、換行
\S 除\s以外的任何字符
\w [a-zA-Z0-9_] 匹配一個單詞
\W [^a-zA-Z0-9] 匹配除\w外的任何字符
\d [0-9] 數字
\D [^0-9] 非數字

注:相同字母的小寫跟大寫在這是互補的,也就是互爲補集,不過須要注意一點,在這裏面沒有包含Unicode字符,不一樣的正則引擎對這些有不一樣的實現,譬如\d有的正則引擎能夠匹配Unicode中的數字,也就是說中文也是有可能匹配的,這個能夠參考各自的語言工具書(不過通常這樣用沒啥問題)。

練習

我這裏使用nodepad++來練習正則表達式,Linux下有些字符處理起來比較麻煩,Java寫起來又太囉嗦,怎麼簡便怎麼來。

找出一段文字中的數字

\d+[0-9]+

這裏使用加號是由於數字至少出現一次纔是合法的,若是使用*則能夠匹配任意位置,由於*能夠不匹配任何字符

日誌裏常根據關鍵字和id來定位,通常如何使用呢?

假設關鍵字爲keyword, id爲13235413,而且id在後面,咱們可使用keyword.*13235413來匹配含有這個模式的一行日誌,這裏加不加問號對咱們沒有影響

找出一行裏含有至少10個單詞的行,假設單詞以空格分割



不存在惟一的答案,我是這樣寫的(\w++ *){10,},第一次寫成了(\w+ *){10,},也就是沒有使用佔有優先量詞,這個表達式是不符合要求的,你們能夠試一下,而後想一想,後面咱們會在涉及到回溯與固化分組相關的時候就能夠明白了。

相關文章
相關標籤/搜索