慕課筆記-JavaScript正則表達式筆記

JavaScript正則表達式筆記

概述

RegExp對象

兩種方法構造RegExp對象

  • 字面量 var reg = /\bis\b /g
  • 構造函數 var reg = new RegExp('\\bis\\b', 'g')

:在Linux中反斜線本身就是特殊字符,所以需要再次轉義,故寫成\\bis\\b的格式

修飾符

  • g: global 全文搜索,不添加的話搜索到第一個匹配停止,添加的話匹配全局
  • i: ignore case 忽略大小寫,默認大小寫敏感
  • m: multipl lines 多行搜索

示例

'He is a boy. Is he?'.replace(/\bis\b/g, '0')  // expected: "He 0 a boy. Is he?"
'He is a boy. Is he?'.replace(/\bis\b/i, '0')  // expected: "He 0 a boy. 0 he?"

元字符

  • 正則表達式有兩種基本字符串類型組成
    • 原義文本字符
    • 元字符
  • 元字符是有特殊含義的非字母字符
  • * + ? $ ^ . | \ ( ) { } [ }

元字符

字符 含義
\t 水平制表符
\v 垂直制表符
\n 換行符
\r 回車符
\0 空字符
\f 換頁符
\cX 與X對應的控制字符(Ctrl+X)

字符類

  • 一般情況下正則表達式一個字符對應字符串的一個字符

  • 字符類

    • 我們可以使用元字符[]構建一個簡單的類
    • 所謂類是指符合某些特性的對象,一個泛指,而不是指某個字符
    • 表達式[abc]把字符串a或b或c歸為一類,表達式可以匹配這類的字符
  • 字符類取反

    • 使用元字符^創建反向類/負向類
    • 反向類的意思是不屬于某類的內容
    • 表達式[^abc]表示不是字符a或b或c的內容
  • 示例

'a1b2c3d4'.replace(/[abc]/g, 'X'); //output: X1X2X3d4
'a1b2c3d4'.replace(/[^abc]/g, 'X'); //output: aXbXcXXX

范圍類

  • 正則表達式提供了范圍類
  • 可以使用[a-z]表示從a到z的任意字符
  • 這是個閉區間,包括a和z本身
  • []中是可以連寫的,例如[a-zA-Z]表示從a到z大小寫匹配

示例:

'a1b2c3d4'.replace(/[a-z]/g, 'Q'); //output: Q1Q2Q3Q4
'2016-09-12'.replace(/[0-9-]/g, 'A'); //output: AAAAAAAAAA

預定義類

預定義字符

字符 等價類 含義
. [^\r\n] 除了回車符和換行符之外的所有字符
\d [0-9] 數字字符
\D [^0-9] 非數字字符
\s [\t\n\x0B\f\r] 空白字符
\S [^\t\n\x0B\f\r] 非空白字符
\w [a-zA-Z_0-9] 查詢字符串(字母,數字下劃線)
\W [^a-zA-Z_0-9] 非單詞字符

邊界

字符 含義
^ 以xxx開頭
$ 以xxx結束
\b 單詞邊界
\B 非單詞邊界

示例

// for \b \B
'This is a boy'.replace(/is/g, '0'); //output: Th0 0 a boy
'This is a boy'.replace(/\bis/g, '0'); //output: This 0 a boy
'This is a boy'.replace(/\Bis/g, '0'); //output: Th0 is a boy
// for ^
'@123@abc@'.replace(/@./g, 'Q'); //output: Q23Qbc@
'@123@abc@'.replace(/^@./g, 'Q'); //output: Q23@abc@
'@123@abc@'.replace(/.@/g, 'Q'); //output: @23QabcQ
'@123@abc@'.replace(/.@$/g, 'Q'); //output: @123@abQ
// for multip line
mulstr="@123\n@456\n@789";
mulstr.replace(/^@\d/g, 'X'); //output:"X23\n@456\n@789"
mulstr.replace(/^@\d/gm, 'X'); //output:"X23\nX456\nX789"

量詞

  • 適用場景:希望匹配連續出現多次的內容的字符串
字符 含義
? 出現零次或一次(最多出現一次)
+ 出現一次或多次(至少出現一次)
* 出現零次或多次(任意次)
{n} 出現n次
{n,m} 出現n到m次
{n,} 至少出現n次
\d{20} //匹配連續出現20次的數字
\d{20}\w\d?\w+\d*\d{3}\w{3,5}\d{3,}

貪婪模式

  • 正則表達式會盡可能多的匹配,直到匹配失敗
  • 非貪婪模式即讓正則表達式盡可能少的匹配,即一旦匹配成功就不再匹配了。做法很簡單,在量詞后面加上 ? 即可。

分組

  • 問題:匹配字符串byron連續出現3次的場景

使用量詞:byron{3}并不能完成目標。因為它只會對緊挨著的n匹配三次,此時,需要使用分組。分組很簡單,直接加上小括號即可。即(byron){3}

示例:

'a1b2c3d4'.replace(/[a-z]\d{3}/g, 'X') //a1b2c3d4
'a1b2c3d4'.replace(/([a-z]\d){3}/g, 'X') //Xd4

或(使用豎線表示)

'ByronCaseper'.replace(/Byron|Caseper/g, 'X') //XX
'ByronsperByrCasper'.replace(/Byr(on|Ca)sper/g, 'X') //XX

反向引用

  • 問題:將2015-12-25 => 12/25/2015
  • 實現方法是使用反向引用,將分組內容使用$進行捕獲,然后再用$進行表示。

示例

'2015-12-25'.replace(/(\d{4})-(\d{2})-(\d{2})/g, '$1/$2/$3')
// 12/25/2015

忽略分組

  • 不想捕獲某些分組,只需要在分組內加上?:就可以了。例如
(?:Bryon).(ok)

前瞻

  • 正則表達式從文本頭部向尾部開始解析,文本尾部方向,稱之為前
  • 前瞻就是再正則表達式匹配到規則的時候,向前檢測是否符合斷言,后顧/后瞻方向相反

注:JavaScript不支持后顧,故不再演示

名稱 正則 含義
正向前瞻 exp(?=asset)
負向前瞻 exp(?!asset)
正向后顧 exp(?<=asset) JS不支持
負向后顧 exp(?<!asset) JS不支持

示例:

'a2*34v8'.replace(/\w(?=\d)/g, 'X')
//"X2*X4X8"
'a2*34v8'.replace(/\w(?!\d)/g, 'X')
//"aX*3XvX"

對象屬性

  • global:是否全文搜索,默認false
  • ignore case:是否大小寫敏感,默認false
  • multiline:多行搜索,默認false
  • lastIndex:是當前表達式匹配內容的最后一個字符的下一個位置
  • source:正則表達式的文本字符串

test和exec方法

  • RegExp.prototype.test(str)
    • 用于測試字符串參數中是否存在匹配正則表達式模式的字符串
    • 如果存在則返回true,否則返回false
  • RegExp.prototype.exec(str)
    • 使用正則表達式模式對字符串執行搜索,并將更新全局RegExp對象的屬性以反映匹配的結果
    • 過沒有匹配的文本則返回null,否則返回一個結果數組
      • index聲明匹配文本的第一個字符的位置
      • input存放被檢索的字符串

:在test方法中,如果匹配全局后有多個結果時,lastindex保存上次執行結果,并向下迭代,直至沒有結果時返回false,則重新回到首位。此時再次執行,則再次循環上面的步驟。

示例:

var reg1 = /\w/;
var reg1 = /\w/g;
while(reg2.test('ab')) {
    console.log(reg2.lastIndex);
}
/*
1
2
*/

非全局調用

  • 調用非全局的RegExp對象的exec()方法時,返回數組
  • 第一個元素是與正則表達式相匹配的文本
  • 第二個元素是與RegExpObject的第一個子表達式相匹配的文不(如果有的話)
  • 第三個元素是與RegExp對的第二個子表達式想匹配的文本(如果有的話),以此類推
var reg3 = /\d(\w)(\w)\d/;
var reg4 = /\d(\w)(\w)\d/g;
var ts = '$1az2bb3cy4dd5ee';

var ret = reg3.exec(ts);

console.log(reg3.lastIndex+'\t'+ret.index+'\t'+ret.toString());
//"0  1 1az2,a,z"
console.log(reg3.lastIndex+'\t'+ret.index+'\t'+ret.toString());
//"0  1 1az2,a,z"

while(ret = reg4.exec(ts)) {
  console.log(reg4.lastIndex + '\t'+ret.index+'\t'+ret.toString());
}
/*
"5  1 1az2,a,z"
"11 7 3cy4,c,y"
*/

可以使用正則的函數

String.prototyp.search(reg)

  • search()方法用于檢索字符串中指定的字符串,或檢索與正則表達式相匹配的子字符串
  • 方法返回一個匹配結果index,查不到返回-1
  • search()方法不執行全局匹配,它將忽略標志g,并且總是從字符串開始進行檢索
'a1b2c3d4'.search(/1/g); //1

String.prototype.match(reg)

  • match()方法將檢索字符串,以找到一個或多個與RegExp匹配的文本
  • RegExp是否具有標志g對結果影響很大
  • 非全局調用
    • 如果RegExp沒有標志g,那么match()方法就只能執行一次匹配
    • 如果沒有找到任何匹配,則返回null
    • 否則返回一個數組,其中存放了了與它找到的匹配文本有關的信息
    • 返回數組的第一個元素存在的是匹配文本,而其他元素存放的是與正則表達式的子表達式匹配的文本
    • 處理常規的數組元素之外,返回的數組還含有兩個對數屬性
      • index聲明匹配文本的其實字符串在字符串的位置
      • input聲明對stringObject的引用
  • 全局調用
    • 如果RegExp具有標志g,則match方法執行全局檢索,找到字符串的所有匹配子字符串
      • 沒有找到匹配,返回null
      • 如果找到一個或多個匹配子串,則返回以數組
    • 數組元素中存放的是字符串所有的匹配子串,而且也沒有index屬性或則input屬性

String.prototype.split(reg)

  • 使用split方法把字符串分割為字符數組
'a,b,c,d'.split(',');//['a','b','c','d']
  • 在一些復雜分割情況下我們可以使用正則表達式解決
'a1b2c3d4'.split(/\d/);//['a','b','c','d']

String.prototype.replace

  • String.prototype.replace(str, replaceStr)
    • str 被替換目標(字符串)
    • replaceStr 替換的字符串
  • String.prototype.replace(reg, replaceStr)
    • str 被替換目標(正則表達式)
    • replaceStr 替換的字符串
  • String.prototype.replace(reg, function)
    • function有四個參數
      • 匹配字符串
      • 正則表達式分組ner,沒有分組則沒有該參數
      • 匹配項在字符串中的index
      • 原字符創
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,702評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,143評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,553評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,620評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,416評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,940評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,024評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,170評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,709評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,597評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,291評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,029評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,407評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,663評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,403評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,746評論 2 370

推薦閱讀更多精彩內容