什么是正則?
正則表達式(regular expression)是一種表達文本模式(即字符串結構)的方法,有點像字符串的模板,常常用來按照“給定模式”匹配文本。比如,正則表達式給出一個 Email 地址的模式,然后用它來確定一個字符串是否為 Email 地址。JAVAScript 的正則表達式體系是參照 Perl 5 建立的。
建立正則表達式
使用內置RegExp構造函數
var reg=new RegExp("martin");
直接建立
var reg=/martin/;
以上兩種建立正則的方式是等效的,,不過一般第二種方式用的更多一些。
接受參數
正則表達式除了接受一個字面量字符參數,還可以接受一個修飾符作為參數。
var reg=/martin/g //var reg=new RegExp("martin","g");
說完基本的正則概念和接受參數,接下來說一下正則的匹配規則,這一塊也是面試和筆試考察的重點。
匹配規則
在說匹配規則之前我們先說一下正則中的字符分類。
字面量字符和元字符
字面量字符:只表示它字面的含義,就像上面代碼中的martin,也就是實際用于匹配的字符。
元字符:不代表字符本身字面的意思,而是有特殊含義的字符,也就是幫助字面量字符達到更好的匹配效果的輔助字符。
其中元字符又分為很多類,具體類型如下:

元字符分類
- 點字符(.)
var reg=/1.3/; //表示匹配1和3之間包含任意一個字符的情況,除特殊符外,如:"1-3","1.3","123"等; //但是一個點只能匹配一個字符,如:"1223"則無法匹配成功
- 位置字符(^和$)
var reg=/^13/; //表示以"13"字符串開頭的字符串 reg.test("134") //true var reg=/13$/; //表示以"13"字符串結束的字符串 reg.test("134") //false reg.test("4 31") //true var reg=/^13$/; //注意:表示從開始到結束位置只有"13"這個字符串 reg.test("13") //true reg.test("1313") //false
注意: /^13$/ 這個正則表達式很容易讓人理解成匹配以字符串"13"開始和結尾的字符串,如:"1313",但實際上它是表示從開始到結束位置只有"13"這個字符串。
- 選擇符(|)
var reg=/11|22||33/; //表示匹配"11"或者"22"或者"33" reg.test("11") //true reg.test("22") //true
注意:選擇符會匹配包括它前后的多個字符,比如 /11|22/ 指的是匹配"11"或者"22",而不是指匹配1或者2,。如果想匹配1或者2,可以添加括號來實現,如:
var reg=/1(1|2)2/; reg.test("112") //true reg.test("122") //true
轉義字符
如果要在正則表達式中使用具有特殊含義的字符,如:$,^等,也就是如果要匹配它們本身,那就需要用到轉義字符了,也就是在他們前面加上""反斜杠,比如要匹配$,則寫成$。
正則表達式中,需要反斜杠轉義的,一共有12個字符:^、.、[、$、(、)、|、*、+、?、{和\。需要特別注意的是,如果使用RegExp方法生成正則對象,轉義需要使用兩個斜杠,因為字符串內部會先轉義一次。
.
var reg=/1$/; //表示匹配字符串"1$",而不是以1結尾的字符串 reg.test("1") //false reg.test("1$") //true
特殊字符
正則表達式對一些不能打印的特殊字符,提供了表達方法。
- cX 表示Ctrl-[X],其中的X是A-Z之中任一個英文字母,用來匹配控制字符。
- [b] 匹配退格鍵(U+0008),不要與b混淆。
- n 匹配換行鍵。
- r 匹配回車鍵。
- t 匹配制表符 tab(U+0009)。
- v 匹配垂直制表符(U+000B)。
- f 匹配換頁符(U+000C)。
- 匹配null字符(U+0000)。
- \xhh 匹配一個以兩位十六進制數(\x00-\xFF)表示的字符。
- \uhhhh 匹配一個以四位十六進制數(\u0000-\uFFFF)表示的 Unicode 字符。
字符類
字符類表示有一系列字符可供選擇,只要匹配其中一個就可以。表示方法為將所有可供選擇的字符都放在方括號內,比如[xyz]表示匹配x、y、z中的任意一個就可以。
var reg=/[abc]/; //表示匹配a,b,c中任一字符皆可 reg.test("hello") //false reg.test("Apple") //true
說到這里同學們應該會想到之前說過的選擇符吧,[xyz]就等效于(x|y|z),兩者可相互轉換。
Q:那既然兩種字符功能可以相互轉換,為啥有了選擇符還要字符類呢?
A:因為字符類除了能表示選擇,還包括另外兩種字符,脫字符和連字符,這兩種字符又有新的功,可以將字符類理解成選擇符的一種超集。
- 脫字符(^)
表示可以匹配除字符類中字符以外的所有字符,因為這個符號和位置字符中的"^"開始位置字符是相同的,所以在使用時要注意區別,直接"^"放在正則表達式開頭的是位置字符,放在"[]"中開頭的"^"表示的是脫字符。
var reg=/^123/; //位置字符 reg.test("1234"); //true var reg=/[^123]/; //脫字符 reg.test("123"); //false reg.test("4") //true
- 連字符(-)
表示匹配連續字符序列中的任意一個字符,如:[abcdef]可以寫成[a-f],[012345678]可以寫成[0-9]等,這大大提升了字符類書寫的簡便性。
var reg=/0-9/; //表示匹配字符串"0-9" reg.test("0") //false reg.test("0-9")//true var reg=/[0-9]/; reg.test("0") //false
==注意:雖然連字符用起來十分簡便,但是一定要避免過度使用連字符,因為連字符往往設定的是一個比較大的范圍,如果不注意可能會匹配到意料之外的一些字符。比如:[A-z],表面上它是要匹配到A-Z和a-z這52個字符,但是實際上在ASCII編碼中,在Z和a之間還有很多其他字符,所以可能機會出現意料之外的匹配效果。
var reg=/[A-z]/; reg.test('['); //true
分析:因為"["字符在Z和a之間,所以也能被匹配到。
預定義模式
預定義模式是指某些常見模式的簡寫方式,可以理解成是內置的正則表達。
- d 匹配0-9之間的任一數字,相當于[0-9]。
- D 匹配所有0-9以外的字符,相當于[^0-9]。
- w 匹配任意的字母、數字和下劃線,相當于[A-Za-z0-9_]。
- W 除所有字母、數字和下劃線以外的字符,相當于[^A-Za-z0-9_]。
- s 匹配空格(包括換行符、制表符、空格符等),相等于[ trnvf]。
- S 匹配非空格的字符,相當于[^ trnvf]。
- b 匹配詞的邊界。
- B 匹配非詞邊界,即在詞的內部。
重復類
模式的精確匹配次數,使用大括號({})表示。{n}表示恰好重復n次,{n,}表示至少重復n次,{n,m}表示重復不少于n次,不多于m次,默認匹配的是單個字符,若想要重復字符串,可以使用括號。
var reg=/12{2,5}3/; //默認表示匹配單個字符"2"的次數為2-5次 reg.test("1223") //true reg.test("12123") //false var reg=/(12){2,5}3/; //表示匹配字符串"12"的次數為2-5次 reg.test("1223") //false reg.test("12123") //true
量詞符
量詞符是內置用來設定某個模式出現的次數的,默認也是匹配單個字符的次數。
- ? 問號表示某個模式出現0次或1次,等同于{0, 1}。
- * 星號表示某個模式出現0次或多次,等同于{0,}。
- + 加號表示某個模式出現1次或多次,等同于{1,}。
貪婪和非貪婪模式
- 貪婪模式(默認):即最大可能匹配,匹配直到下一個字符不滿足匹配規則為止,上面說的三個量詞符,默認模式都為貪婪模式。
var s = 'aaa'; var reg=/a+/; s.match(reg); //["aaa"]
- 非貪婪模式:即最小可能匹配,匹配到一個滿足匹配規則的字符就停止,將貪婪模式改為非貪婪模式只需要在量詞符后面加一個問號。
var s = 'aaa'; var reg=/a+?/; s.match(reg); //["a"]
總結:
- *?:表示某個模式出現0次或多次,匹配時采用非貪婪模式。
- +?:表示某個模式出現1次或多次,匹配時采用非貪婪模式。
修飾符
修飾符(modifier)表示模式的附加規則,放在正則模式的最尾部,有g,i,m三種修飾符。
修飾符可以單個使用,也可以多個一起使用。
// 單個修飾符 var reg = /test/i; // 多個修飾符 var reg = /test/ig;
- g修飾符
默認情況下,第一次匹配成功后,正則對象就停止向下匹配了。g修飾符表示全局匹配(global),加上它以后,正則對象將匹配全部符合條件的結果,主要用于搜索和替換。
var s = 'aaa'; var reg=/a+?/; s.match(reg); //["a"] var s = 'aaa'; var reg=/a+?/g; s.match(reg); //["a","a","a"]
- i修飾符
默認情況下,正則對象區分字母的大小寫,加上i修飾符以后表示忽略大小寫(ignorecase)
var s = 'Aaa'; var reg=/a/; s.match(reg); //["a"] var s = 'Aaa'; var reg=/a/i; s.match(reg); //["A"]
- m修飾符
m修飾符表示多行模式(multiline),會修改^和$的行為。默認情況下(即不加m修飾符時),^和$匹配字符串的開始處和結尾處,加上m修飾符以后,^和$還會匹配行首和行尾,即^和$會識別換行符(n)。
var s = 'abn ab'; var reg=/ab$/m; s.match(reg); //["ab"] var s = 'abn ab'; var reg=/ab$/gm; s.match(reg); //["ab","ab"]會按行進行匹配,會識別n換行符,這里的第一行以ab結尾,第二行也以ab結尾
練習題
1.常用的11位手機號碼驗證的正則?
2.常用的郵箱驗證的正則?