在快速入門
一文中,示例都是經過test()
方法演示,本文會繼續介紹正則的其它用法(以JS
語言爲例)html
正則對象正則表達式
test
方法compile
方法exec
方法字符串的正則應用c#
match
方法replace
方法search
方法split
方法有兩種方法能夠建立並獲得一個正則表達式對象數組
字面量聲明方式函數
var reg = /abc/g;
顯式建立code
var reg =new RegExp("abc", "g");
上文生成正則對象中最後有用到g
,其實這就是生成正則的可選項標記,能夠組合使用,以下regexp
g
全文匹配,即匹配一個成功後,若是沒有結束,會繼續匹配i
忽略大小寫匹配m
多行匹配能夠經過以下示例進一步瞭解htm
/g
的用法對象
加上/g
後會全局搜索全部匹配結果blog
var str = 'abcabcabc'; // ['abc', index: 0, input: "abcabcabc"] str.match(/abc/); // ['abc', 'abc', 'abc'] str.match(/abc/g);
/i
的用法
加上/i
後大小寫一視同仁,不少時候,若是不加/i
,很容易出現大小寫不匹配的錯誤(好比去除字符串中script
標籤時)
var str = 'Script'; // null str.match(/script/); // ["Script", index: 0, input: "Script"] str.match(/script/i);
/m
的用法
多行匹配比較少用到,但在一些場景下不得不用,好比下例中,只有\m
多行匹配的狀況下才能正常的將每一行的行尾(\n
造成不一樣的行)的數字替換成#
,不然默認會認爲只有一行
var str = 'a1\nb1\nc1\nd1\ne1\nf1'; /** * a1 * b1 * c1 * d1 * e1 * f# */ str.replace(/\d+$/g, '#') /** * a# * b# * c# * d# * e# * f# */ str.replace(/\d+$/mg, '#')
正則表達式中,用圓括號包圍的就是子表達式(子模式)
通常,在match
的非全局匹配中或exec
中,在匹配完整個正則表達表達式後,都會再次匹配子表達式
另外,在字符串的replace
與split
中,子表達式也會常常用到
var str = 'a1.b2.c3.d4'; // 第一個結果是 整個正則表達式的匹配,以後則分別是子表達式的匹配 /(\w)(\d)[.]/.exec(str); // ["a1.", "a", "1", index: 0, input: "a1.b2.c3.d4"]
pattern.test(str);
檢索字符串中是否存在指定模式,匹配成功則返回true
,不然返回false
var str = 'abcdefg'; /^abc/.test(str); // true /^abce/.test(str); // false
reg.compile(pattern);
編譯正則表達式,編譯以後正則的執行速度會提升
編譯的時候也能夠改變檢索模式或者改變可選項標識
var str = 'abcdabcdabc'; var reg = /abc/; reg.test(str); // true reg.compile(); reg.test(str); // true,僅僅是被編譯,沒有被改變 reg.compile(/aB/); reg.test(str); // false,匹配式改爲了aB,所以不匹配 reg.compile(/aB/i); reg.test(str); // true,改爲了aB而且忽略大小的形式,所以匹配
pattern.exec(str);
在字符串中檢索特定的模式,匹配成功則返回找到的值,不然返回null
有兩種狀況
第一種:非全局匹配
若是沒有找到,則返回null
找到則返回一個數組,arr[0]
是匹配結果,餘下元素是arr[0]中匹配圓括號中子表達式的結果,以及最後的index
和input
並且非全局模式中,不會保存index
,也就是說無論匹配多少次,結果都是同樣的
var str = 'a1.b2.c3.d4'; var reg1 = /(\w)(\d)[.]/; reg1.exec(str); // ["a1.", "a", "1", index: 0, input: "a1.b2.c3.d4"] reg1.exec(str); // ["a1.", "a", "1", index: 0, input: "a1.b2.c3.d4"] reg1.exec(str); // ["a1.", "a", "1", index: 0, input: "a1.b2.c3.d4"] /abc/.exec(str); // null
第二種:g
全局匹配
正則的exec
全局匹配能夠保存index
,而且下一次繼續匹配時,將不會是從新從0
開始,而是從保存的index
開始
var str = 'a1.b2.c3.d4'; var reg2 = /(\w)(\d)[.]/g; reg2.exec(str); // ["a1.", "a", "1", index: 0, input: "a1.b2.c3.d4"] reg2.exec(str); // ["b2.", "b", "2", index: 3, input: "a1.b2.c3.d4"] reg2.exec(str); // ["c3.", "c", "3", index: 6, input: "a1.b2.c3.d4"] /abc/.exec(str); // null
上文中提到的都是正則對象上的方法,但實際上,JS
的String
對象也支持正則表達式
match
是字符串中最經常使用的方法
str.match(pattern);
若是pattern
中有g
,表明全局匹配,則返回的數組包含全部匹配結果
若是無g
,則返回的數組的第1
個元素(arr[0]
)是第一個匹配結果,餘下元素是arr[0]
中匹配圓括號中子表達式的結果
var str = 'a.b2.c3.d445.e'; str.match(/\d[.]/); // ["2.", index: 3, input: "a.b2.c3.d445.e"] // 非全局匹配下,而且有圓括號子表達式,先匹配整個正則表達式一次 // 而後在匹配結果中再匹配子表達式 str.match(/(\d)[.]/); // ["2.", "2", index: 3, input: "a.b2.c3.d445.e"] // g 模式下是對整個正則表達式(包括圓括號子表達式)進行全局匹配 str.match(/(\d)[.]/g); // ["2.", "3.", "5."]
字符串中用來快速替換的方法,有多種用法
第一種狀況
str.replace(str1, str2);
第一個參數是字符串,那麼返回的結果只有str1
被替換成str2
了
var str = 'a.b2.c3.d4'; // 只會替換 . 一次 str.replace('.', '#'); // a#b2.c3.d445.e
第二種狀況
str.replace(pattern, str2);
第一個參數是正則表達式,此時若是是g
全局匹配模式,會替換全部的匹配結果爲str2
,不然只會替換一個匹配結果
var str = 'a.b2.c3.d4'; str.replace(/[.]/, '#'); // a#b2.c3.d445.e str.replace(/[.]/g, '#'); // a#b2#c3#d445#e
另外此模式下,str2
還可使用一些有特殊含義的特殊字符,例如
var str = 'a1.b2.c3.d4'; // $2和$1分別表明第2個,第1個子表達式 str.replace(/(\w)(\d)[.]*/g, '$2$1~'); // 1a~2b~3c~4d~
str2
中可用的特殊字符表
字符 | 替換 |
---|---|
$1,$2,...,$99 | 匹配第1~99個pattern中的圓括號子表達式的文本 |
$& | 匹配pattern的子串 |
$` | 匹配子串的左邊文本 |
$' | 匹配子串的右邊文本 |
$$ | 美圓符號 |
第三種狀況
str.replace(pattern, func);
這種模式下,第二個參數爲一個函數,func
將會在每個匹配結果中調用,func
返回的字符串將做爲替換文本,func
接收的參數,第一個是匹配pattern
的字符串,以後的參數(多是多個)是匹配該pattern
中某個圓括號子表達式的字符串,在這以後的參數就是index
(匹配結果的位置),再以後就是完整的input
var str = a1.b2.c3.d4; // 最終結果爲: 1a~2b~3c~4d~ str.replace(/(\w)(\d)[.]*/g, function(word, child1, child2, index, input) { console.log(word); // 依次打印的是a1. b2. c3. d4 console.log(child1); // 依次打印的是a b c d console.log(child2); // 依次打印的是1 2 3 4 console.log(index); // 依次打印的是0 3 6 9 console.log(input); // 每次都是打印 a1.b2.c3.d4 return child2 + child1 + '~'; });
返回第1
個與patten匹配的字符串子串的起始位置,若是找不到,則返回-1
,不支持全局檢索,也就是說,會省略g
var str = 'abcdefg1234567'; str.search(/efg/); // 4 str.search(/efg/g); // 4 str.search(/aabc/g); // -1
split
方法可讓一個字符串分割成數組,一樣忽略g
str.split(pattern, limit); // pattern爲字符串或正則
將str
拆分爲子串組成的數組,子串中不包括pattern
(特例除外)。limit
是可選參數,指定返回的數組的最大長度
特例: 若是pattern
包含圓括號子表達式,則匹配這個圓括號子表達式的子串(不是匹配整個正則)會包含在返回數組中
var str = 'a1.b2.c3.d4'; str.split(/\d[.]/); // ["a", "b", "c", "d4"] // 包含了圓括號的子串,返回數組中出現了匹配圓括號的子串 str.split(/(\d)[.]/); // ["a", "1", "b", "2", "c", "3", "d4"] var str2 = '.b2.c3.'; // 3.後面沒有字符了,可是因爲它符合匹配,因此後續結果中會多一個"" str2.split(/\d[.]/); // [".b", "c", ""] // 同上,只不過圓括號中的內容也在返回結果中 str.split(/(\d)[.]/); // [".b", "2", "c", "3", ""]
初次發佈2017.07.06
於我的博客
http://www.dailichun.com/2017/07/15/regularExpressionBaseUsage.html