淺入正則(二)

with (javascript)

前一篇淺入正則(一)瞭解了實例化一個RegExp對象RegExp的原型方法RegExp的對象屬性這些基礎,大體知道正則怎麼用,這一篇主要想了解一下正則怎麼寫。javascript

元字符

元字符表隨便就查獲得,但這是會寫正則最重要的基礎,這裏簡單分紅兩類並按個人理解簡單註釋。java

  • 運算符 & 限定符正則表達式

{
    "\": "除語義類元字符中的使用,\ 爲轉義字符,好比想要匹配一個'(',直接使用'('會被認做分組的開始,須要使用\轉義, '/\(/'",
    "^": {
        "開頭": "在非'[]'中使用,表示匹配開頭的意思,若是RegExp對象設置多行(m)屬性,也會匹配換行符\n及\r以後的位置",
        "非": "在'[]'中,表示取反,例如:'/[^a]/',表示匹配不是a的字符"
    },
    "$": "匹配結束的位置,若是RegExp對象設置多行(m)屬性,也會匹配換行符\n及\r以前的位置",
    "*": "任意的意思,表示匹配前面緊接着的子表達式0次或屢次",
    "+": "表示匹配前面緊接着的子表達式1次或屢次,也就是最少1次",
    "?": {
        1: "表示匹配前面緊接着的子表達式0次或1次,也就是最多1次",
        2: "非貪婪模式:前提是緊跟在其餘限定符後面,好比'*'、'+'、'{n,m}'等,表示儘量少的匹配,好比'{n,m}',例如: '/\d{4,6}?/g',假如使用這個正則test一段字符串'123456abc',則會盡量少的匹配,也就是每次test只匹配4個,而後lastIndex被置爲4,默認狀況下爲貪婪模式,每次會匹配6個,lastIndex會重置爲6,若是沒法匹配6個纔會嘗試匹配5個,4個"
    },
    "{n}": "表示匹配前面緊接着的子表達式n次,n爲非負整數",
    "{n,}": "表示匹配前面緊接着的子表達式n次或更屢次,也就是最少n次,n爲非負整數",
    "{n,m}": "表示匹配前面緊接着的子表達式n次到m次,也就是最少匹配n次,最多匹配m次,n <= m 且n和m均爲非負整數",
    ".": "除'\n'外的任意字符",
    "|": "或,例如'/a|bcd/'能夠匹配'a'或者'bcd','/(a|b)cd/'能夠匹配'acd'或者'bcd'",
    "-": "僅當在'[]'中能夠表示鏈接符,'/[a-z]/'、'/A-Z/'、'/0-9/'分別表示a到z、A到Z、0到9,其餘時間就表示中劃線",
    "[]": "字符集合,表示中括號中的任意字符,好比'/[acb123ABC]/'表示匹配到'acb123ABC'中任意一個就能夠",
    "()": "分組,和咱們日常的加減運算中的()差很少,能夠理解爲肯定優先級的意思,不過js正則中的()分組能夠經過'$1 - $9'獲取匹配結果中,每個分組對應的匹配值,也就是'$1'也就是第一個分組的子表達式匹配成功的結果,例如:'abc123ef'.replace(/(\w)(\d){3}/g,'$2$1'),例子中,匹配(一個字母)緊接着(一個數字)循環了三次,'$1'就是後面緊接着數字的一個字母,也就是'c','$2'就是一個數字,也就是'(\d)'的最後一個匹配結果'3',由於數字循環了三次,因此三個數字會被替換成'$1',而c會被替換成'$2',結果就是'ab3cef'",
    "(?:)": "和()差很少一個意思,只是()中的分組內容不會被存儲到'$1 - $9'的集合中",
    "(?=)": "正向前瞻,也就是前面的表達式緊接着的表達式,要符合(?=)的=後面跟着的表達式,例如:'/[a-z](?=\d)/',只會匹配後面緊接着數字的小寫字母,可是數字並不會出如今匹配結果中且不會被存儲到'$1 - $9'的集合中",
    "(?!)": "負向前瞻,也就是前面的表達式緊接着的表達式,要符合(?!)的 != 後面跟着的表達式,例如:'/[a-z](?!\d)/',只會匹配後面緊接着不是數字的小寫字母,可是數字並不會出如今匹配結果中且不會被存儲到'$1 - $9'的集合中"
}

基礎的運算符和限定符無非就這幾個,說到運算符就有優先級,上面的運算符的優先級爲:segmentfault

{
    "一級": "'\'",
    "二級": "'()'、'(?:)'、'(?=)'、'[]'",
    "三級": "'*'、"+"、'?'、'{n}'、'{n,}'、'{n,m}'",
    "四級": "'^'、'$'、'其餘元字符及字符'",
    "五級": "'|'",
}
  • 語義類元字符數組

{
    "\b": "單詞邊界,也就是前面或者後面要跟着個空格",
    "\B": "非單詞邊界,也就是必須在單詞中間,先後不能有空格",
    "\d": "匹配一個數字字符,等價於'[0-9]'",
    "\D": "匹配一個非數字字符,等價於'[^0-9]'",
    "\w": "匹配任意單詞字符和下劃線'_',等價於'[a-zA-Z0-9_]'",
    "\W": "匹配任意非單詞字符及非下劃線,等價於'[^a-zA-Z0-9_]'",
    "\s": "匹配任意空白字符,含空格、製表符、換頁符等",
    "\S": "匹配非空白字符",
    //···還有不少不經常使用的,用時再查吧
}

前一篇筆記只解析了RegExp對象的原型方法,可是對於正則表達式,一些字符串的方法一樣可使用在正則上。code

replace

replace也屬於常用的一個方法,在具體到和正則表達式一塊兒使用時是:stringObject.replace(RegExpObject,string|function),上例子:regexp

var str1 = "2017-07-12";
var reg1 = /(\d{4})-(\d{2})-(\d{2})/g;
str1.replace(reg1, function(a,b,c,d,e){
    // a/b/c/d/e分別表明: 匹配結果/第一個分組匹配值/第二個分組匹配值/第三個分組匹配值/匹配成功的第一個字符的index值
    console.log(a,b,c,d);                //2017-07-12 2017 07 12,0
    return c + "/" + d + "/" + b;
})
console.log(str1);                       //07/12/2017
  • 須要注意的是,string是沒有replaceAll的方法的,須要全局替換請在正在中設置全局屬性g對象

match

math方法也是string的方法,match方法用法和exec很類似,一樣返回數組。ip

  • 非全局正則調用,輸出結果和exec類似,無匹配結果則返回null,有則返回數組,分別存放每個子表達式匹配的結果,同時具備index和input兩個屬性:字符串

var reg1 = /([a-zA-Z]\d)+([\u4e00-\u9fa5])+/;
//匹配 (大小寫字母連着一個數字) 至少一次 (再連着漢字) 至少一次
var str1 = "a11B2老cd3李e45好";
var result = str1.match(reg1);
console.log(result);                     //["B2老", "B2", "老"]

這個結果和exec的結果徹底同樣;

  • 全局正則調用,數組只存放全部匹配的整個正則的子字符串,而不存放正則子表達式匹配的子字符串,也沒有index和input的屬性:

var reg2 = /([a-zA-Z]\d)+([\u4e00-\u9fa5])+/g;

//匹配 (大小寫字母連着一個數字) 至少一次 (再連着漢字) 至少一次
var str2 = "a11B2老cd3李e45好";
var result1 = str2.match(reg2);
var result2 = str2.match(reg2);
var result3 = str2.match(reg2);

console.log(result1,result2,result3);                //["B2老", "d3李"] ["B2老", "d3李"] ["B2老", "d3李"]
console.log(result1.index,result2.input,result3);    //undefined undefined ["B2老", "d3李"]
執行屢次均只輸出每個匹配完整正則的子字符串,同時也沒有index和input的屬性。

search

search方法返回的就是正則第一次匹配成功的開始位置,用法是stringObject.search(regexp);同時serch方法只須要匹配成功一次,不會重置laseIndex屬性,每次都從字符串起始位置開始搜索,也會忽略全局搜索g

var reg3 = /([a-zA-Z]\d)+([\u4e00-\u9fa5])+/g;
var reg4 = /([a-zA-Z]\d)+([\u4e00-\u9fa5])+/g;
var str3 = "a11B2老cd3李e45好";
str3.search(reg3);        //3
str3.search(reg3);        //3
str3.search(reg4);        //3
str3.search(reg4);        //3
屢次搜索和是否全局均不會影響搜索結果

無論多麼複雜的正則,都是用本節中的元字符寫出來的,而在複雜的正則,用法無非也就上節和這一節中所記錄的方法。關鍵在於經常使用才能熟練,深刻才能理解。這兩節筆記只是淺入,在實踐中摸索實踐才能真的深刻淺出,一塊兒加油。


淺入正則(一)

相關文章
相關標籤/搜索