1. 程式人生 > 實用技巧 >正則表示式入門

正則表示式入門

1、正則表示式

正則表示式(regular expression)是一個描述字元規則的物件。

2、正則表示式的作用

前端往往有大量的表單資料校驗的工作,採用正則表示式會使得資料校驗的工作量大大減輕,如郵箱驗證,手機號碼,等等。比起用字串的函式來判斷簡單,易用。

3、正則表示式的定義

JS中定義正則表示式有兩種方式,一種是通過建構函式,一種是通過/…/,也就是兩個斜槓。

3.1、方式一

// 使用RegExp這個物件(建構函式)
// 語法
// pattern: 模板字串
// attributes:字串,可選。包含屬性 "g"、"i" 和 "m",分別用於指定全域性匹配、區分大小寫的匹配和多行匹配。ECMAScript 標準化之前,不支援 m 屬性。如果 pattern 是正則表示式,而不是字串,則必須省略該引數

var reg = new RegExp(pattern, [attributes]);

//例如:
var reg= new RegExp(‘study’);    //表示含有study,(預設區分大小寫)
var reg = new RegExp('study', 'ig'); // 其中i 表示忽略大小寫,g 表示全域性匹配

3.2、方式二

// 使用常量方式直接宣告
//語法
var reg = /study/;  
//等價於:var reg= new RegExp('study'); 
//等價於:var reg= new RegExp(/study/);

4、正則表示式的使用

使用正則表示式來測試某個字串是否符合正則表示式所規定的規則。

正則表示式可以被用於RegExp的exectest方法以及 String的matchreplacesearchsplit方法。

match:一個在字串中執行查詢匹配的String方法,它返回一個數組或者在未匹配到時返回null。

var s = '_x_x';
var r1 = /x/g;
var r2 = /y/;

s.match(r1) // ["x","x"]
s.match(r2) // null

search:一個在字串中測試匹配的String方法,它返回匹配到的位置索引,或者在失敗時返回-1。

'_x_x'.search(/x/) // 1

replace:一個在字串中執行查詢匹配的String方法,並且使用替換字串替換掉匹配到的子字串。

'aaa'.replace('a', 'b') // "baa"
'aaa'.replace(/a/, 'b') // "baa"
'aaa'.replace(/a/g, 'b') // "bbb"

// 清除字串首尾空格
var str = '  #id div.class  ';
str.replace(/^\s+|\s+$/g, '')

split:一個使用正則表示式或者一個固定字串分隔一個字串,並將分隔後的子字串儲存到陣列中的String方法。

// 非正則分隔
'a,  b,c, d'.split(',')
// [ 'a', '  b', 'c', ' d' ]

// 正則分隔,去除多餘的空格
'a,  b,c, d'.split(/, */)
// [ 'a', 'b', 'c', 'd' ]

// 指定返回陣列的最大成員個數為2個
'a,  b,c, d'.split(/, */, 2)
[ 'a', 'b' ]

5、正則表示式屬性和方法

5.1、例項屬性

// 一類是修飾符相關,返回一個布林值,表示對應的修飾符是否設定。
RegExp.prototype.ignoreCase  //返回一個布林值,表示是否設定了i修飾符。
RegExp.prototype.global      //返回一個布林值,表示是否設定了g修飾符。
RegExp.prototype.multiline   //返回一個布林值,表示是否設定了m修飾符。

//示例
var r = /abc/igm;
r.ignoreCase // true
r.global // true
r.multiline // true

// 另一類是與修飾符無關的屬性
RegExp.prototype.lastIndex  //返回一個整數,表示下一次開始搜尋的位置。該屬性可讀寫,但是隻在進行連續搜尋時有意義,詳細介紹請看後文。
RegExp.prototype.source     //返回正則表示式的字串形式(不包括反斜槓),該屬性只讀。

//示例
var r = /abc/igm;
r.lastIndex // 0
r.source // "abc"

5.2、例項方法

RegExp.prototype.test()

描述:正則例項物件的test方法返回一個布林值,表示當前模式是否能匹配引數字串。
語法:regexObj.test(str)
引數:str 用來與正則表示式匹配的字串
返回值:如果正則表示式與指定的字串匹配 ,返回true;否則false

示例:

/cat/.test('cats and dogs') // true

RegExp.prototype.exec()

描述:正則例項物件的exec方法,用來返回匹配結果。如果發現匹配,就返回一個數組,成員是匹配成功的子字串,否則返回null

語法:regexObj.exec(str)

引數:str 要匹配正則表示式的字串。

返回值:如果匹配成功,exec() 方法返回一個數組,並更新正則表示式物件的屬性。返回的陣列將完全匹配成功的文字作為第一項,將正則括號裡匹配成功的作為陣列填充到後面。如果匹配失敗,exec() 方法返回 null。

示例:

var s = '_x_x';
var r1 = /x/;
var r2 = /y/;

r1.exec(s) // ["x"]
r2.exec(s) // null

6、特殊字元

^ // 匹配一行的開頭,/^a/匹配"abc",而不匹配“bca“
$ // 匹配一行的結尾,/a$/匹配“bca",而不匹配"abc" 

* // 匹配前面元字元0次或多次,/ba*/將匹配b,ba,baa,baaa ,相當於{0,}
+ // 匹配前面元字元1次或多次,/ba+/將匹配ba,baa,baaa ,相當於 {1,}
? // 匹配前面元字元0次或1次,/ba?/將匹配b,ba ,相當於{0,1}
    
x|y  // 匹配x或y ,/a|b/ 將匹配只要出現a或者b的字串,不含a與b的不匹配

{n}  // 精確匹配n次 ,/d{4}/  將匹配,出現連續4個d的字串
{n,} // 匹配n次以上 ,/d{4,}/將匹配,出現連續4個及4個以上的d的字串
{n,m} // 匹配n-m次,/d{4,8}/將匹配,出現連續4到8個d的字串


 
 
\d //匹配0-9之間的任一數字,相當於[0-9]。
\D //匹配所有0-9以外的字元,相當於[^0-9]。
\w //匹配任意的字母、數字和下劃線,相當於[A-Za-z0-9_]。
\W //除所有字母、數字和下劃線以外的字元,相當於[^A-Za-z0-9_]。
\s //匹配空格(包括換行符、製表符、空格符等),相等於[ \t\r\n\v\f]。
\S //匹配非空格的字元,相當於[^ \t\r\n\v\f]。
\b //匹配詞的邊界。
\B //匹配非詞邊界,即在詞的內部。

示例:
// \s 的例子
/\s\w*/.exec('hello world')    // [" world"]

// \b 的例子
/\bworld/.test('hello world') // true
/\bworld/.test('hello-world') // true
/\bworld/.test('helloworld') // false

// \B 的例子
/\Bworld/.test('hello-world') // false
/\Bworld/.test('helloworld') // true

7、轉義字元(量字元)

\f     換頁符
\n     換行符
\r     回車
\t     製表符
\v     垂直製表符
\/     一個 / 直接量
\\     一個 \ 直接量
\.     一個 . 直接量 
\*     一個 * 直接量
\+     一個 + 直接量
\?     一個 ? 直接量
\|     一個 | 直接量
\(     一個 ( 直接量
\)     一個 ) 直接量
\[     一個 [ 直接量
\]     一個 ] 直接量
\{     一個 { 直接量
\}     一個 } 直接量

8、方括號

[abc]               //查詢abc中的任意一個字元。 
[^abc]              //查詢除abc的一個字元。 
[0-9]               //查詢任何從 0 至 9 的數字。
[a-z]               //查詢任何從小寫 a 到小寫 z 的字元。 
[adgk]              //查詢給定集合內的任何一個字元。 
(aa|ddd|gg|kkkk)    // 同上,選取aa,ddd,gg,kkkk中的一個
// 示例:
// [a-z]*表示任意個 a-z 中的字元,[0-9]*表示任意個 0-9 的字元
var pattern = /g[a-zA-Z]*gle/; //[a-z]*表示任意個 a-z 中的字元
var str = 'google';
alert(pattern.test(str));//true
str = 'go12agle';
alert(pattern.test(str));//false
str = 'ggle';
alert(pattern.test(str));//true
var pattern = /g[0-9]*gle/; //[0-9]*表示任意個 0-9 的字元

// 加上^ 表示非(即排除)	
var pattern = /g[^0-9]*gle/; //[^0-9]*表示任意個非 0-9 的字元
var str = 'google';
alert(pattern.test(str));//true
str = 'g12gle';
alert(pattern.test(str));//false
str = 'ggle';
alert(pattern.test(str));//true	

9、組匹配

正則表示式的括號表示分組匹配,括號中的模式可以用來匹配分組的內容。

/fred+/.test('fredd')    // true
/(fred)+/.test('fredfred') // true

上面程式碼中,第一個模式沒有括號,結果+只表示重複字母d,第二個模式有括號,結果+就表示匹配fred這個詞。

var m = 'abcabc'.match(/(.)b(.)/);
// m = ['abc', 'a', 'c']

10、常用正則表示式

檢查郵政編碼//共 6 位數字,第一位不能為 0
/^[1-9]\d{5}$/
檢查檔案壓縮包  //xxx.zip\xxx.gz\xxx.rar
/^\w+\.(zip|gz|rar)$/       
刪除多餘空格  //
str.replace(/\s+/,'');
刪除首尾空格
str.replace(/^\s+/,''); //去除開頭的空格
str.replace(/\s+$/,'');  // 去除結尾的空格
//刪除所有的空格
str.replace(/\s/g,'');
//刪除前後的空格
str.replace((^\s+)|(\s+$),'')

電子郵件( xxxxx @ xxxx(.xxxx)+)
/^\w+@\w+(\.\w+)+$/          
如: [email protected]; [email protected]   
手機號(1開頭任意數字)  1(3|5|7|8|4)\d{9}
/^1\d{10}$/

身份證
/^\d{17}(\d|X)$/       
  422422 19660101 5810
  421087 19890101 121X 
^[1-9]\d{5}[19|20]\d{2}\d{7}(\d|X)$
日期  (合法日期格式:xxxx-xx-xx或 xxxx/xx/xx或xxxx.xx.xx)
/^\d{4}[-\/\.]\d{2}[-\/\.]\d{2}$/
只能輸入中文
str.replace(/[^\u4e00-\u9fa5]/g,'');
賬戶名只能使用數字字母下劃線,且數字不能開頭,長度在6-15之間
/^[a-zA-Z_]\w{5,14}$/
驗證IP
(xxx.)xxx.xxx.xxx|  
254.245.255.255
240.196.19.5
/^((25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)$/

    
將所有的bag、beg、big和bog改為bug
str.replace(/(bag|beg|big|bog)/g,'bug');

將所有方法foo(a,b,c)的例項改為foo(b,a,c)
str.replace(/foo\(([^,]+),([^,]+),([^,]+)\)/g,'foo($2,$1,$3)');

假設有一個多字元的片斷重複出現,例如:
Billy tried really hard
Sally tried really really hard
Timmy tried really really really hard
Johnny tried really really really really hard
而你想把"really"、"really really",以及任意數量連續出現的"really"字串換成一個簡單的"very“

str.replace(/(really\s)+/gi,'very');