Javascript中使用RegExp的簡略指南

風靈使發表於2018-10-26

前言

RegExp是Javascript中的一個內建物件。使用它可以在javascript中進行一些正則方面的操作。本文打不打算詳細的介紹RegExp的具體內容,比如子匹配、分組、惰性匹配等等這些內容的具體用法。本文僅從實用的角度來闡述regexp在javascript中的一些常用以及基本方法。關於RegExp的具體文件,可參閱w3school或者MDN。

建立

在Javascript中有兩種方式來建立一個regexp。一種是使用new RegExp(pattern[, flags]),另一種是使用/pattern/[flags]。前者建立了一個regexp物件,後者是一個物件字面量。

這裡有兩點稍微提一下,

  • 使用第一種方式時,我們可以傳遞一個字串,也可以傳遞一個正則字面量。
  • 使用字串建立regexp物件時,注意元字元的轉義。

下面是幾個例子,

var reg1 = /ab+c/i;
var reg2 = new RegExp('ab+c', 'i');
var reg3 = new RegExp(/ab+c/, 'i');
var reg4 = /\w+/;
var reg5 = new RegExp('\\w+');

方法

在Javascript中,跟regexp物件關聯最為密切的一般都是String物件。支援regexpString方法有如下幾個,

方法 說明
search 檢索與正規表示式相匹配的值
match 找到一個或多個正規表示式的匹配
replace 替換與正規表示式匹配的子串
split 把字串分割為字串陣列

上面的4個方法都可以使用regexp作為引數,而且根據傳入的regexp可能返回的結果會有很大的不同。

除此之外,regexp物件本身也有一些方法,他們是,

方法 說明
compile 編譯正規表示式
exec 檢索字串中指定的值。返回找到的值,並確定其位置。
test 檢索字串中指定的值。返回 true 或 false。

關於各個方法在javascript中的具體使用示例,請繼續往下看??
示例

下面,我將會使用一系列的真實示例來闡述regexp以及相關方法的用法。

// 測試`test`方法
var reg = /he/;
reg.test('hehe'); // true
reg.test('boy'); // false
reg.test('HEHE'); // false 因為regexp預設是大小寫敏感的
var reg2 = /he/i;
reg2.test('HEHE'); // true
reg2.test('I am a good boy, and she is a bad girl.'); // true 只要被匹配的字串中包含he(HE、hE、He)即可。
var reg3 = /^he/i;
reg3.test('She is a good girl'); // false 因為he不是字串的首部。
var reg4 = /he$/i;
reg4.test('She loves he'); // true 因為he是字串的尾部。
var reg5 = /^he$/i;
reg5.test('he'); // true 因為字串是以h開始,以e結束,且中間沒有任何其他字元。
var reg6 = /\s/; // 元字元`\s`匹配任何空白字元,包括空格、製表符、換頁符等等  
reg6.test('ge jiawen'); // 字串中有空格
var reg7 = /^[a-z]/; // 元字元`[]`匹配指定範圍內的任意字元
reg6.test('good123'); // true 字串中必須要是以字母開頭
// 僅僅知道了字串是否匹配模式還不夠,我們還需要知道哪些字元匹配了模式
var reg8 = /^[a-z]+\s+\d+$/i; // 量詞`+`,表示至少匹配一次
reg8.test('Ubuntu 8'); // true 因為匹配到了版本號
// 我們使用regexp的exec方法,返回一個陣列,第一個元素為匹配的內容,後續的陣列元素為子匹配的內容(如果有子匹配的話)
var ret = reg8.exec('Ubuntu 8');
console.log(ret[0]); // ['Ubuntu 8']
// 提取匹配內容中的數字
var reg9 = /\d+/;
reg9.exec(reg8.exec('Ubuntu 8')); // ['8']
// 要提取'Ubuntu 8'中的數字,我們還是使用子匹配
var reg10 = /^[a-z]+\s+(\d+)/i; // 一般我們使用`()`來設定一個子匹配(或者叫匹配分組)
reg10.exec('Ubuntu 8'); // ['Ubuntu 8', '8']
// 可以設定多個子匹配
var reg11 = /^[a-z]+\s+(\d+)\.(\d+)$/i;
reg11.exec('Ubuntu 14.04'); // ['Ubuntu 14.04', '14', '04']
// 使用replace,進行字串替換
var str = 'some money';
str.replace('some', 'much'); // much money
str.replace(/\s+/, '%'); // much%money
// 使用regexp的全域性匹配標誌,進行多次匹配。
// 如果不進行全域性匹配,那麼regexp將在匹配成功一次後終止匹配。反之則匹配整個字串。
var str2 = 'some      money'; // 包含了多個空格字元
str2.replace(/\s/, '%'); // some%   money
str2.replace(/\s/g, '%'); // some%%%%money
// split方法使用regexp。
// 在`[]`中使用`^`表示範圍取反。
var str3 = 'a_bc-d=e--f';
str3.split(/[^a-z]+/g); // ["a", "bc", "d", "e", "f"]
// search使用regexp。
var str4 = 'My age is 25 age.';
str4.search(/\d+/); // 10,表示匹配字串的開始位置。如果沒有匹配到則為-1
// 使用match方法。
var str5 = 'My name is Larry. Hello everyone.';
str5.match(/[A-Z]/); // ['M'] 因為我們沒有全域性匹配。所以匹配成功一次就終止了
str5.match(/[A-Z]/g); // ["M", "L", "H"]
str5.match(/\b[a-z]\b/ig); // ["My", "name", "is", "Larry", "Hello", "everyone"] 匹配所有的單詞
str5.match(/\b[a-z]{2}\b/ig); // ["My", "is"] 匹配所有2個字元的單詞
// 捕獲分組與非捕獲分組。
// 捕獲分組將`(abc)`中的`abc`匹配內容也放到結果陣列中。而非捕獲分組則不會。
/(abc){2}/.exec('abcabc'); // ["abcabc", "abc"]
/(?:abc){2}/.exec('abcabcabc') // ["abcabc"]
// 候選,也就是‘或者’的意思
/^a|c$/.test('asssc'); // true 因為將匹配開始的字元a,或者結束位置的c
/^(a|bc)$/.test('abc') // false 因為匹配的字串必須是a或者bc
// 分組與反向引用。
// `test`,`match`等方法對包含分組的regexp進行操作時,會將分組儲存起來,通過反向引用可以拿到分組。
var reg = /(A?(B?(C?)))/;
reg.test('ABC'); // 反向引用被儲存在RegExp物件的靜態屬性$1—$9中  
console.log(RegExp.$1 + ", " + RegExp.$2 + ", " + RegExp.$3); // ABC, BC, C
var reg2 = /\d+(\D)\d+\1\d+/; // 在regexp中可以使用`\1`來反向引用匹配到的分組
'2008-1-1'.test(reg2); // true
'2008-1_1'.test(reg2); // false
var reg3 = /(\d)\s(\d)/;
'1234 5678'.replace(reg3, '$2 $1'); // '5678 1234'
// 正向前瞻(?=)與負向前瞻(?!)
// 正規表示式引擎在執行正向前瞻或者負向前瞻時,正規表示式引擎會留意字串後面的部分,然後卻不會真實的移動匹配指標index。
// 示例:如果我要匹配一個後面跟一個數字的單詞,但是僅僅返回這個單詞不包括數字。
var reg = /[a-z]+(?=\d+)/;
var str = 'I am a good2 boy.';
str.match(reg); // ['good']
// 示例:如果我要匹配一個後面不跟一個數字的單詞,但是僅僅返回這個單詞不包括數字。
var reg = /[a-z]+(?!\d+)\b/g;
var str = 'one1 two2 three four4';
str.match(reg); // ["three"]

以上程式碼塊中的內容基本上就是javascript中使用regexp的方方面面了。掌握這些方法,在編寫javascript程式碼時,特別是針對一些字串進行處理時,使用regexp往往會具有很高的效率。不過,javascript中的regexp僅僅涵蓋了正規表示式的基本及常見用法。要想了解更多更詳細的內容,可以參閱相關專門講述正規表示式的書籍。

相關文章