簡潔而神祕的語法:正則表達式
正則表達式的語法很是簡潔,並且對於不熟悉正則表達式的人,看起來簡直很神祕。有時,正則表達式中看起來好像處處都充斥着反斜槓、圓括號和方括號。而只要理解正則表達式中每一個字符串和元字符的做用,就能本身編寫正則表達式或者分析其餘開發人員編寫的正則表達式。測試
元字符是指在正則表達式模式中具備特殊含義的字符或字符組合:\b,.,*,還有\d.正則表達式裏還有更多的元字符,好比\s匹配任意的空白符,包括空格,製表符(Tab),換行符,中文全角空格等。\w匹配字母或數字或下劃線或漢字等。編碼
示例:spa
\ba\w*\b匹配以字母a開頭的單詞——先是某個單詞開始處(\b),而後是字母a,而後是任意數量的字母或數字(\w*),最後是單詞結束處(\b)。.net
\d+匹配1個或更多連續的數字。這裏的+是和*相似的元字符,不一樣的是*匹配重複任意次(多是0次),而+則匹配重複1次或更屢次。ci
空格會致使含義改變:開發
若是無心間在正則表達式中插入了空格,就會完全改變正則表達式的含義,從而使得應該匹配的內容不在匹配,而不想匹配的內容卻匹配了。因此,在創建正則表達式模式時,必需要當心處理空格符。字符串
沒有統一的語法標準:數學
正則表達式多樣化是由於沒有統一的標準定義正則表達式的語法。正則表達式最先是由於被Perl語言採用才引發人們注意的,因爲遵循不一樣程度的精確性,致使了其餘語言和應用程序中的正則表達式語法不相同。io
不一樣環境下的字符含義不一樣:
正則表達式容易令人感到疑惑的另外一個緣由是,單個字符或者元字符,其使用環境不一樣,含義也會不一樣。例如,^元字符在某些語言的正則表達式中用於表示一行的開始位置。但就是在同一種語言環境下,^元字符類中使用時,就變成了否認的含義(或非、取反、補集——即不包括的意思。)有上可知,正則表達式模式^and匹配字符序列and位於一行開頭的狀況,而正則表達式[^and]則表示一個包含a、b、d的字符類。
字符轉義:
若是你想查找元字符自己的話,好比你查找.,或者*,就出現了問題:你沒辦法指定它們,由於它們會被解釋成別的意思。這時你就得使用\來取消這些字符的特殊意義。所以,你應該使用\.和\*。固然,要查找\自己,你也得用\\.
例如:deerchao\.net匹配deerchao.net,C:\\Windows匹配C:\Windows。
重複:
咱們常常看到的無非就是*,+,{2},{5,12}這幾個匹配重複的方式了。下面是正則表達式中全部的限定符(指定數量的代碼,例如*,{5,12}等):
代碼/語法 | 說明 |
* | 重複零次或更屢次 |
+ | 重複一次或更屢次 |
? | 重複零次或一次 |
{n} | 重複n次 |
{n,} | 重複n次或更屢次 |
{n,m} | 重複n到m次 |
下面是一些使用重複的例子:
Windows\d+匹配Windows後面跟1個或更多數字
^\w+匹配一行的第一個單詞(或整個字符串的第一個單詞,具體匹配哪一個意思得看選項設置)
分支條件:
正則表達式裏的分支條件指的是有幾種規則,若是知足其中任意一種規則都應該當成匹配,具體方法是用|把不一樣的規則分隔開。聽不明白?不要緊,看例子:
0\d{2}-\d{8}|0\d{3}-\d{7}這個表達式能匹配兩種以連字號分隔的電話號碼:一種是三位區號,8位本地號(如010-12345678),一種是4位區號,7位本地號(0376-2233445)。
\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}這個表達式匹配3位區號的電話號碼,其中區號能夠用小括號括起來,也能夠不用,區號與本地號間能夠用連字號或空格間隔,也能夠沒有間隔。你能夠試試用分支條件把這個表達式擴展成也支持4位區號的。
\d{5}-\d{4}|\d{5}這個表達式用於匹配美國的郵政編碼。美國郵編的規則是5位數字,或者用連字號間隔的9位數字。之因此要給出這個例子是由於它能說明一個問題:使用分支條件時,要注意各個條件的順序。若是你把它改爲\d{5}|\d{5}-\d{4}的話,那麼就只會匹配5位的郵編(以及9位郵編的前5位)。緣由是匹配分支條件時,將會從左到右地測試每一個條件,若是知足了某個分支的話,就不會去再管其它的條件了。
分組:
咱們已經提到了怎麼重複單個字符(直接在字符後面加上限定符就好了);但若是想要重複多個字符又該怎麼辦?你能夠用小括號來指定子表達式(也叫作分組),而後你就能夠指定這個子表達式的重複次數了,你也能夠對子表達式進行其它一些操做(後面會有介紹)。
(\d{1,3}\.){3}\d{1,3}是一個簡單的IP地址匹配表達式。要理解這個表達式,請按下列順序分析它:\d{1,3}匹配1到3位的數字,(\d{1,3}\.){3}匹配三位數字加上一個英文句號(這個總體也就是這個分組)重複3次,最後再加上一個一到三位的數字(\d{1,3})。
IP地址中每一個數字都不能大於255,你們千萬不要被《24》第三季的編劇給忽悠了……
不幸的是,它也將匹配256.300.888.999這種不可能存在的IP地址。若是能使用算術比較的話,或許能簡單地解決這個問題,可是正則表達式中並不提供關於數學的任何功能,因此只能使用冗長的分組,選擇,字符類來描述一個正確的IP地址:((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)。
理解這個表達式的關鍵是理解2[0-4]\d|25[0-5]|[01]?\d\d?,這裏我就不細說了,你本身應該能分析得出來它的意義。
反義:
有時須要查找不屬於某個能簡單定義的字符類的字符。好比想查找除了數字之外,其它任意字符都行的狀況,這時須要用到反義:
代碼/語法 | 說明 |
\W | 匹配任意不是字母,數字,下劃線,漢字的字符 |
\S | 匹配任意不是空白符的字符 |
\D | 匹配任意非數字的字符 |
\B | 匹配不是單詞開頭或結束的位置 |
[^X] | 匹配除了x之外的任意字符 |
[^aeiou] | 匹配除了aeiou這幾個字母之外的任意字符 |
例子:\S+匹配不包含空白符的字符串。
<a[^>]+>匹配用尖括號括起來的以a開頭的字符串。