天天看點

JS之RegExp的使用基本文法RegExp執行個體屬性RegExp示例方法*RegExp構造函數的屬性

RegExp的使用

  • 基本文法
    • 字面量建立
    • RegExp構造函數
  • RegExp執行個體屬性
  • RegExp示例方法
    • exec()
    • test()
    • toLocaleString()和toString()
  • *RegExp構造函數的屬性

基本文法

ECMAScript通過RegExp類型支援正規表達式,正規表達式使用類似Perl的簡潔文法來建立。關于正規表達式的簡單介紹可以參考部落客的另一篇文章:正規表達式。

字面量建立

文法如下:

  pattern代表模式,模式可以是任何簡單或複雜的正規表達式,包括字元類、限定符、分組、向前查找和反向作用。每個正規表達式可以帶零個或者多個的flags(标記),用于控制正規表達式的行為,常見的标記值有:

flags 含義
g 全局模式,表示查找字元串的全部内容,而不是找到第一個比對的内容就結束
i 不區分大小寫,表示在查找比對的時候忽略pattern和字元串的大小寫
m 多行模式,表示查找到一行文本末尾時會繼續查找
y 粘附模式,表示隻查找從lastInex開始及之後的字元串
u Unicode模式,啟用Unicode比對
s dotAll模式,表示元字元.比對任何字元,包括"\n"和"\r"

  使用不同模式和标記可以建立出不同的正規表達式,比如:

let pattern1 = /abc/g; //比對字元串中所有的abc
	let pattern2 = /abc/i; //比對字元串中第一個出現的abc
	let pattern3 = /abc/gi; //比對字元串中所有的abc,并且忽略大小寫
           

  正規表達式中還會涉及到元字元的概念,元字元常見的有:{ 、} 、( 、) 、[ 、] 、\ 、^ 、$ 、| 、? 、* 、+ 、.(點)。元字元在正規表達式中都有着特殊的功能,要比對元字元本身的話,就需要用到轉義字元:“\”,例如:

let pattern1 = /[ab]d/g; //比對所有ad或bd
	let pattern2 = /\[ab\]d/g; //比對所有的[ab]d
           

RegExp構造函數

  除了上文的字面量建立正規表達式,RegExp構造函數也可以用于建立正規表達式,它的一般形式為:

let pattern1 = new RegExp("abc", "g");
	//與let pattern1 = /abc/g;等價
           

  這裡還需要注意的是,RegExp構造函數的兩個參數都是字元串,是以在某些情況下需要進行二次轉義,例如:

let pattern1 = /\[ab\]c/g;
	let pattern2 = new RegExp("\\[ab\\]c","g");
           

  這裡的pattern1和pattern2是等價的,其實也可以簡單地了解為如果想要用RegExp構造函數表示的話,轉義符号的數量是字面量的兩倍。

  使用RegExp構造函數還可以基于原有的正規表達式,選擇性地修改它們的标記,例如:

let pattern1 = /abc/g;
	console.log(pattern1); //輸出/abc/g
	let pattern2 = new RegExp(pattern1); 
	console.log(pattern2); //輸出/abc/g
	let pattern3 = new RegExp(pattern1, "i");
	console.log(pattern3); //輸出/abc/i
           

RegExp執行個體屬性

  RegExp執行個體常見的屬性有:

屬性 代表
global 布爾值,表示是否設定了g标記
ignoreCase 布爾值,表示是否設定i标記
unicode 布爾值,表示是否設定了u标記
sticky 布爾值,表示是否設定了y标記
mutiline 布爾值,表示是否設定了m标記
dotAll 布爾值,表示是否設定了s标記
source 正規表達式的字面量字元串(這裡與字面量的差別就是沒有開頭和結尾的斜杠)
flags 正規表達式的标記字元串

RegExp示例方法

exec()

  RegExp示例的主要方法是exec(),主要用于配合捕獲組,(可以了解為一個括号就是一個捕獲組),exec方法隻接收一個參數,就是要應用模式的字元串,如果找到了比對項,就會傳回包含第一個比對資訊的數組;如果沒找到比對項,則傳回null。這裡要注意的是,傳回的數組雖然是Array的執行個體,但包含兩個額外的屬性:index和input,index是字元串中比對模式的起始位置,input是要查找的字元串。傳回數組的第一個元素是比對整個模式的字元串,其他元素是與表達式中的捕獲組比對的字元串。如果模式中沒有捕獲組,則數組隻有一個元素,具體例子如下:

let str = 'abcabce';
	let pattern = /(.)b(.)/g;
	let result = pattern.exec(str);
	console.log(result);
	console.log(result.input);
	console.log(result.index);
	console.log(result[0]);
	console.log(result[1]);
	console.log(result[2]);
           

結果如下:

JS之RegExp的使用基本文法RegExp執行個體屬性RegExp示例方法*RegExp構造函數的屬性

  如果模式設定了全局模式,則每次調用exec()方法會傳回一個比對的資訊。如果沒有設定全局标記,則無論對同一個字元串調用多少次exec(),也隻會傳回第一個比對的資訊,如:

let str = 'cat, bat, sat, fat';
	let pattern = /.at/;
	let result = pattern.exec(str);
	console.log(result.index); //0
	console.log(result[0]); //cat
	console.log(pattern.lastIndex); //0
	
	result = pattern.exec(str);
	console.log(result.index); //0
	console.log(result[0]); //cat 
	console.log(pattern.lastIndex); //0
           

  而如果當我們設定了全局标記:

let str = 'cat, bat, sat, fat';
	let pattern = /.at/g;
	let result = pattern.exec(str);
	console.log(result.index); //0
	console.log(result[0]); //cat
	console.log(pattern.lastIndex); //3
	
	result = pattern.exec(str);
	console.log(result.index); //5
	console.log(result[0]); //bat
	console.log(pattern.lastIndex); //8
           

  而當模式設定了粘附标記y,則每次調用exec()都隻會在lastIndex的位置上尋找比對項。粘附标記會覆寫全局标記。具體例子如下:

let str = 'cat, bat, sat, fat';
	let pattern = /.at/y;
	let result = pattern.exec(str);
	console.log(result.index); //0
	console.log(result[0]); //cat
	console.log(pattern.lastIndex); //3
	
	result = pattern.exec(str);
	//以索引3對應的字元開頭找不到比對項,exec()傳回null
	console.log(result); //null
	//exec()沒有找到比對項,于是lastIndex設定為0
	console.log(pattern.lastIndex); //0
	
	//如果将lastIndex設定為5,讓exec()可以找到下一個比對項
	pattern.lastIndex = 5;
	result = pattern.exec(str);
	console.log(result.index); //5
	console.log(result[0]); //cat
	console.log(pattern.lastIndex); //8
           

test()

  test()用于測試特定的數值序列。如果輸入的文本與模式比對,則顯示比對成功的消息,一般用于驗證使用者的輸入:

let str = '123-123-12';
	let pattern = /\d{3}-\d{3}-\d{2}/g;
	let result = pattern.test(str);
	if(result){
		console.log('符合格式'); //輸出符合格式
	}else{
		console.log('不符合格式');
	}
           

toLocaleString()和toString()

  這兩個方法都是用于獲得正規表達式字面量的形式,無論正規表達式是字面量建立的還是RegExp構造函數建立的:

let pattern1 = new RegExp("abc", "g");
	let pattern2 = /abc/g;
	console.log(pattern1.toLocaleString()); //輸出/abc/g
	console.log(pattern1.toString()); //輸出/abc/g
	console.log(pattern2.toLocaleString()); //輸出/abc/g
	console.log(pattern2.toString()); //輸出/abc/g
           

*RegExp構造函數的屬性

  RegExp構造函數本身也有幾個屬性,這些屬性适用于作用域中的所有正規表達式,而且會根據最後執行的正規表達式操作而變化,這些屬性都有全名和簡寫,具體如下:

全名 簡寫 說明
input $_ 最後搜尋的字元串
lastMatch $& 最後比對的文本
lastParen $+ 最後比對的捕獲組
leftContext $` input字元串中出現在lasMatch前的文本
rightContext $’ input字元串中出現在lasMatch後的文本

具體使用如下:

let text = "this is a sentence";
	let pattern = new RegExp("(.)s","g");
	if(pattern.test(text)){
		console.log(RegExp.input);
		console.log(RegExp.leftContext);
		console.log(RegExp.rightContext);
		console.log(RegExp.lastMatch);
		console.log(RegExp.lastParen);
	}
           

結果:

JS之RegExp的使用基本文法RegExp執行個體屬性RegExp示例方法*RegExp構造函數的屬性

也可以使用簡寫:

let text = "this is a sentence";
	let pattern = new RegExp("(.)s","g");
	if(pattern.test(text)){
		console.log(RegExp["$_"]);
		console.log(RegExp["$`"]);
		console.log(RegExp["$'"]);
		console.log(RegExp["$&"]);
		console.log(RegExp["$+"]);
	}
           

  RegExp構造函數還有幾個屬性,可以存儲最多9個捕獲組的比對項,通過RegExp.$1~RegExp.$9來通路。

RegExp構造函數的所有屬性都沒有任何Web标準出處,是以不要在生産環境中使用它們。