爲了匹配規定模式的文本
爲了守護世界的和平
咱們是穿梭在銀河的正則表達式
就是這樣~喵~html
好用的正則表達式可視化工具: https://regexper.com/git
//字面量 var regExp1 = /pattern/flags; //或用構造函數 var regExp2 = new RegExp(pattern[, flags]);
pattern
:正則表達式的匹配模式flags
:可選,正則表達式的標識,也可選多個。g
全局匹配,i
忽略大小寫,m
匹配多行github
一顆超簡單的栗子:正則表達式
var regExp = /abc/; "abcdefg".replace(regExp, "WOW"); // "WOWdefg"
字符 | 舉例 | 含義 |
[] | [xyz] | xyz中任意一個字符 等價於[x-z] |
[^] | [^xyz] | 匹配任意不在xyz中的一個字符,等價於[^x-z] (注意與^x區分,後者表示匹配以x開頭的字符) |
[-] | [1-3] | 匹配123中的任意一個字符,等價於[123]。注意:連字符只有出如今方括號中才表示連續的字符序列。 |
預約義模式就是某些經常使用模式的簡寫。數組
字符 | 含義 |
. | 除\r和\n以外的任意字符,等價於[^\r\n] |
\d | 數字0-9,等價於[0-9] |
\D | 非數字字符,等價於[^0-9] |
\w | 字母數字下劃線,等價於[A-Za-z0-9_] |
\W | 非字母數字下劃線,等價於[^A-Za-z0-9_] |
\s | 空白符 |
\S | 非空白符 |
\n | 換行符 |
正則模式中,須要用斜槓轉義的:數據結構
* + ? $ ^ . | \ ( ) { } [ ]
須要特別注意的是,若是使用RegExp方法生成正則對象,轉義須要使用兩個斜槓,由於字符串內部會先轉義一次。dom
字符 | 舉例 | 含義 |
^ | ^a | 以a開頭(注意與[^]區分,後者表示匹配不在[^]中的元素) |
$ | a$ | 以a結尾 |
\b | \bsmart,smart\b | 單詞邊界,即[A-Za-z0-9_]以外的字符 |
\B | \Bsmart | 非單詞邊界 |
舉個栗子說 \b 和 \B :函數
"You are smart, but she is smarter.".replace(/smart\b/,"kind"); //"You are kind, but she is smarter." "You are smart, but she is smarter.".replace(/smart\B/,"kind"); //"You are smart, but she is kinder."
if(看不懂){ 就置幾動手試試吧 (ง •̀_•́)ง }工具
字符 | 含義 |
? | 匹配前面的模式 0或1次 {0,1} |
* | 匹配前面的模式 0或屢次 {0,} |
+ | 匹配前面的模式 1或屢次 {1,} |
{n} | 匹配前面的模式 n次 |
{n,} | 匹配前面的模式 至少n次 |
{n,m} | 匹配前面的模式 至少n次,至多m次 |
{0,m} | 匹配前面的模式 至多m次 |
x(?=y) | 只有x後面緊跟着y時,才匹配x,可是y不是匹配結果的一部分。例如/smart(?=girl)/ 只有後面有girl 時,才匹配smart ,可是girl 不是匹配結果的一部分。 |
x(?!y) | 只有x後面不緊跟着y時,才匹配x。例如/\d+(?!\.)/ 只有一個數字後面沒有緊跟着小數點時纔會匹配該數字,/\d+(?!\.)/.exec("3.141") 匹配結果是141 。 |
默認是貪婪模式匹配,即匹配儘量多的字符。post
var regExp1 = /\d{3,6}/; "1234567890".replace(regExp1, "X"); //"X7890"
若想手動開啓懶惰模式,須要在模式後加 ?
var regExp1 = /\d{3,6}?/; "1234567890".replace(regExp1, "X"); //"X4567890"
分組又叫「子表達式」,把完整的正則表達式分紅一個個小組,而後反過來用「組號」去引用這些小組就叫「反向引用」。
用例子來講:
//無分組 var regExp1 = /abc{2}/; //這樣量詞{2}只能匹配到c一個字符 //分組 var regExp2 = /(abc){2}/; //這樣量詞{2}就能夠匹配到abc三個字符啦 //同時 abc 也有了一個組號 $1
再看一個栗子:
var reg = /(\d{1}).*(\d{2}).*(\d{3})/; "1sss23sss456".replace(reg,"$1?$2?$3"); //"1?23?456"
上面的栗子換一種使用分組的方式:
var reg = /(\d{1}).*(\d{2}).*(\d{3})/; var result = reg.exec("1sss23sss456"); console.log(result[1]+"-"+result[2]+"-"+result[3]); //"1-23-456"
組匹配很是有用,下面是一個匹配網頁標籤的例子:
var tagName = /<([^>]+)>[^<]*<\/\1>/; // \1 就是第一個組匹配的內容 tagName.exec("<b>bold</b>")[1]
上面代碼稍加修改,就能夠捕獲帶有屬性的標籤:
var html = '<b class="hello">Hello</b><i>world</i>'; var tag = /<(\w+)([^>]*)>(.*?)<\/\1>/g; var match = tag.exec(html); match[1] // "b" match[2] // " class="hello"" match[3] // "Hello" match = tag.exec(html); match[1] // "i" match[2] // "" match[3] // "world"
非捕獲組: (?:x)
表示不返回該組匹配的內容,即匹配的結果中不出現這個括號。
測試當前正則是否能匹配目標字符串,返回布爾值。
var reg = /\d{2}/; var str = "1sss23sss456"; reg.test(str); //true
在目標字符串中執行一次正則匹配操做,返回匹配的子字符串。
var reg = /\d{2}/; var str = "1sss23sss456"; var result = reg.exec(str); result[0]; //23 result.index; //4 result.input; //"1sss23sss456"
返回一個字符串,其值爲該正則對象的字面量形式。覆蓋了Object.prototype.toString() 方法。
var reg = /\d{2}/; reg.toString(); // "/\d{2}/"
返回替換後的值
var reg = /\d{2}/; var str = "1sss23sss456"; str.replace(reg,"?"); //"1sss?sss456"
經常使用於消除首尾空格:
var str = ' abc def ggg '; str.replace(/^\s+|\s+$/g, ''); // 'abc def ggg'
replace
方法的第二個參數能夠使用美圓符號來指代所替換的內容:
> $& 指代匹配的子字符串。 > $` 指代匹配結果前面的文本。 > $' 指代匹配結果後面的文本。 > $n 指代匹配成功的第n組內容,n是從1開始的天然數。 > $$ 指代美圓符號$。
replace
方法的第二個參數還能夠是一個函數,將每個匹配內容替換爲函數的返回值。這個函數能夠接受多個參數,第一個參數是捕捉到的內容,第二個參數開始是捕捉到的組匹配(有多少個組匹配,就對應有多少個參數)。此外,最後還能夠添加兩個參數,倒數第二個是捕捉到的內容在整個字符串中的位置,最後一個參數是原字符串。下面是一個網頁模板替換的例子:
var prices = { 'pr_1': '$1.99', 'pr_2': '$7.99', 'pr_3': '$9.99', }; var template = '<span id="pr_1"></span><span id="pr_2"></span>'; template.replace( /(<span id=")(.*?)(">)(<\/span>)/, function(match, p1, p2, p3 ,p4) { return p1 + p2 + p3 + prices[p2] + p4; }); //<span id="pr_1">$1.99</span><span id="pr_2"></span>
注意:第二個分組要加 ?
開啓懶惰模式,不然正則表達式默認的貪婪模式會匹配儘量多的字符。貪婪模式下,上面的例子中第二個分組會匹配到pr_1"></span><span id="pr_2
這一長串,從而沒法匹配到咱們但願的字符串。
與exec()
相似,返回匹配的子字符串。
var reg = /\d{2}/; var str = "1sss23sss456"; str.match(reg); //["23"]
與exec()
的區別在於:當正則表達式加了g標識符時,結果不一樣。看栗子:
var reg = /\d{2}/g; var str = "1sss23sss456"; reg.exec(str); //["23"] str.match(reg); //["23","45"]
返回匹配的首字符的位置。
var reg = /\d{2}/; var str = "1sss23sss456"; str.search(reg); //4
返回分割後的數組。
var reg = /\d{2}/; var str = "1sss23sss456"; str.split(reg); //["1sss","sss","6"]
寫一個匹配手機號的正則(第一位是1,第二位是[3,4,5,7,8]中的一個,後面還有9位數字)
寫一個匹配 2017-01-01 或 2017/01/01 這兩種格式日期的正則表達式
————答案:
/^1[34578]\d{9}$/
/^\d{4}[-/]\d{2}[-/]\d{2}$/
var re = /(\w+)\s(\w+)/; var str = "John Smith"; var newstr = str.replace(re, "$2, $1"); console.log(newstr); //Smith, John
var s = "Please yes\nmake my day!"; s.match(/yes.*day/); // null s.match(/yes[^]*day/); //'yes\nmake my day'
var url = "http://xxx.domain.com"; console.log(/[^.]+/.exec(url)[0]); // "http://xxx" console.log(/[^.]+/.exec(url)[0].substr(7)); // "xxx"
匹配除了.以外的任意元素,一到多個字符。
參考: