Stories

Detail Return Return

RegExp基礎語法 - Stories Detail

匹配模式

創建正則表達式對象時,可以設置’m’、’i’、’g’這三個標誌,分別對應多行模式、不區分大小模式和全局模式三種

全局模式 g:
默認地,第一次匹配成功後,正則對象就停止向下匹配了。g 修飾符表示全局匹配(global),設置’g’標誌後,正則對象將匹配全部符合條件的結果,主要用於搜索和替換

console.log('1a,2a,3a'.replace(/a/,'b'));//'1b,2a,3a'
console.log('1a,2a,3a'.replace(/a/g,'b'));//'1b,2b,3b'
特點:javascript 中的正則表達式最大的特點是不支持空白,必須寫在一行中
//匹配ab
console.log(/ab/.test("ab")); //true
console.log(/ ab/.test("ab")); //false
console.log(/a b/.test("ab")); //false
console.log(/ab /.test("ab")); //false

元字符

元字符         名稱              匹配對象
.             點號               單個任意字符(除回車\r、換行\n、行分隔符\u2028和段分隔符\u2029外)
[]            字符組             列出的單個任意字符
[^]           排除型字符組        未列出的單個任意字符
?             問號               匹配0次或1次
*             星號               匹配0交或多次
+             加號               匹配1次或多次
{min,max}     區間量詞            匹配至少min次,最多max次
^             脱字符             行的起始位置
$             美元符             行的結束位置
|             豎線               分隔兩邊的任意一個表達式
()            括號               限制多選結構的範圍,標註量詞作用的元素,為反向引用捕獲文本
\1,\2...      反向引用            匹配之前的第一、第二...組括號內的表達式匹配的文本

轉義字符

  • 【1】因為元字符有特殊的含義,所以無法直接匹配。如果要匹配它們本身,則需要在它們前面加上反斜槓()

    右方括號]和右花括號}不需要轉義
  • 【2】’'加非元字符,表示一些不能打印的特殊字符

    \0        NUL字符\u0000
    [\b]      匹配退格符\u0008,不要與\b混淆
    \t        製表符\u0009
    \n        換行符\u000A
    \v        垂直製表符\u000B
    \f        換頁符\u000C
    \r        回車符\u000D
    \xnn      由十六進制數nn指定的拉丁字符
    \uxxxx    由十六進制數xxxx指定的Unicode字符(\u4e00-\u9fa5代表中文)
    \cX       控制字符^X,表示ctrl-[X],其中的X是A-Z之中任一個英文字母,用來匹配控制字符
    ‘'加任意其他字符,默認情況就是匹配此字符,也就是説,反斜線()被忽略了

字符組

  • 範圍
    正則表達式通過連字符(-)提供了範圍表示法,可以簡化字符組
/[0123456789]/
//等價於
/[0-9]/
/[abcdefghijklmnopqrstuvwxyz]/
//等價於
/[a-z]/
  • 排除
    字符組的另一個類型是排除型字符組,在左方括號後緊跟一個脱字符’^’表示,表示在當前位置匹配一個沒有列出的字符,所以1表示 0-9 以外的字符

在字符組內部,脱字符’^’表示排除,而在字符組外部,脱字符’^’表示一個行錨點

^符號是元字符,在字符組中只要^符號不挨着左方括號就可以表示其本身含義,不轉義也可以

//匹配abc和^符號
console.log(/[a-c^]/.test("^")); //true
console.log(/[a-c\^]/.test("^")); //true
console.log(/[\^a-c]/.test("^")); //true
  • 簡記

    \d     數字,等同於[0-9]
    \D     非數字,等同於[^0-9]
    \s     空白字符,等同於[\f\n\r\t\u000B\u0020\u00A0\u2028\u2029]
    \S     非空白字符,等同於[^\f\n\r\t\u000B\u0020\u00A0\u2028\u2029]
    \w     字母、數字、下劃線,等同於[0-9A-Za-z_](漢字不屬於\w)
    \W     非字母、數字、下劃線,等同於[^0-9A-Za-z_]
  • 量詞

    // 默認情況下,量詞都是貪婪模式(greedy quantifier),即匹配到下一個字符不滿足匹配規則為止
    {n}       匹配n次
    {n,m}     匹配至少n次,最多m次
    {n,}      匹配至少n次
  • 相當於{0,}
  • 相當於{1,}

    懶惰模式(lazy quantifier)和貪婪模式相對應,在量詞後加問號’?’表示,表示儘可能少的匹配,一旦條件滿足就再不往下匹配
{n}?       匹配n次
{n,m}?     匹配至少n次,最多m次
{n,}?      匹配至少n次
??         相當於{0,1}
*?         相當於{0,}
+?         相當於{1,}

括號

括號有兩個功能,分別是分組和引用。具體而言,用於限定量詞或選擇項的作用範圍,也可以用於捕獲文本並進行引用或反向引用

  • 分組

    //希望字符串'ab'重複出現2次,應該寫為(ab){2}
    console.log(/(ab){2}/.test("abab")); //true
    console.log(/(ab){2}/.test("abb")); //false
    console.log(/ab{2}/.test("abab")); //false
    console.log(/ab{2}/.test("abb")); //true
    
    //身份證長度有15位和18位兩種
    /\d{15}(\d{3})?/;
  • 捕獲

    //RegExp.$1\RegExp.$2\RegExp.$3……到RegExp.$9分別用於存儲第一、第二……第九個匹配的捕獲組。在調用exec()或test()方法時,這些屬性會被自動填充
    console.log(/(\d{4})-(\d{2})-(\d{2})/.test("2016-06-23")); //true
    console.log(RegExp.$1); //'2016'
    console.log(RegExp.$2); //'06'
    console.log(RegExp.$3); //'23'
    console.log(RegExp.$4); //''
    
    //在replace()方法中也可以引用分組,形式是$num,num是對應分組的編號
    console.log("2000-01-01".replace(/(\d{4})-(\d{2})-(\d{2})/g, "$3-$2-$1")); //'01-01-2000'
  • 反向引用
    反向引用允許在正則表達式內部引用之前捕獲分組匹配的文本,形式是\num,num 表示所引用分組的編號

    //開始標籤
    <([^>]+)>
    //標籤內容
    [\s\S]*?
    //匹配成對的標籤
    /<([^>]+)>[\s\S]*?<\/\1>/
    
    console.log(/<([^>]+)>[\s\S]*?<\/\1>/.test('<a>123</a>'));//true
    console.log(/<([^>]+)>[\s\S]*?<\/\1>/.test('<a>123</b>'));//false

    選擇

    //開頭
    (0|\+86)?
    //前3位
    13\d|14[579]|15[0-35-9]|17[0135-8]|18\d
    //後8位
    \d{8}
    
    //手機號碼
    var phone = /(0|\+86)?(13\d|14[579]|15[0-35-9]|17[0135-8]|18\d)\d{8}/;
    console.log(phone.test('13453250661'));//true
    console.log(phone.test('1913250661'));//false
    console.log(phone.test('1345325061'));//false

    斷言

    在正則表達式中,有些結構並不真正匹配文本,而只負責判斷在某個位置左/右側是否符合要求,這種結構被稱為斷言(assertion),也稱為錨點(anchor),常見的斷言有 3 種:單詞邊界、行開頭結尾、環視

  • 單詞邊界
    正則表達式提供了專用的單詞邊界(word boundary),記為\b,它匹配的是’單詞邊界’位置,而不是字符。

    console.log(/\ban\b/.test("an apple")); //true
    console.log(/\ban\b/.test("a an")); //true
    console.log(/\ban\b/.test("an")); //true
    console.log(/\ban\b/.test("and")); //false
    console.log(/\ban\b/.test("ban")); //false
  • 起始結束
    常見的斷言還有^和$,它們分別匹配字符串的開始位置和結束位置,所以可以用來判斷整個字符串能否由表達式匹配
  • 環視
    javascript 只支持正序環視,相當於只支持向前看,不支持往回看;而正序環視又分為肯定正序環視和否定正序環視
    肯定正序環視的記法是(?=n),表示前面必須是 n 才匹配;否定正序環視的記憶法是(?!n),表示前面必須不是 n 才匹配
console.log(/a(?=b)/.exec("abc")); //['a']
console.log(/a(?=b)/.exec("ac")); //null
console.log(/a(?!b)/.exec("abc")); //null
console.log(/a(?!b)/.exec("ac")); //['a']

console.log(/a(?=b)b/.exec("abc")); //['ab']

優先級

//從上到下,優先級逐漸降低
\                            轉義符
() (?!) (?=) []              括號、字符組、環視
* + ? {n} {n,} {n,m}         量詞
^ $                          起始結束位置
|                            選擇

  1. 0-9 ↩

Add a new Comments

Some HTML is okay.