2013年11月11日 星期一

JavaScript 正規表示式(Regular Expression)資料整理

JavaScript 正規表示式資料:
特殊字元表示法
表示法 說明 ASCII
\0 null \x00
\b backspace
例:[\b] 符合backspace
\x08
\n newline \x0A
\r 回列首(Carriage Return) \x0D
\f 換頁(Form Feed) \x0C
\t tab \x09
\v 垂直 tab \x0B
\xhh 編碼為 hh 的字元 (hh 為兩個 16 進位數字)
\uhhhh 編碼為 hhhh 的字元 (hhhh 為四個 16 進位數字)
\cX 組合鍵
X 是從A~Z 的字元,表示 Control+A ~ Control+Z

Character Classes (Character Sets)
Character 說明
[...] 在列舉的範圍內
例:[xyz]
[^...] 不在列舉的範圍內
例:[^xyz]
. 任何字元,\n 除外(除非在 /s 單列模式下)
等於[^\x0A\x0D\u2028\u2029]

. 在[]中,只代表單純的.字元,所以若要匹配所有字元,可用[\s\S]
\w 字詞字元。即 [a-zA-Z0-9_]
\W 非字詞字元。即 [^a-zA-Z0-9_]
\d 數字。即 [0-9]
\D 非數字。即 [^0-9]
\s 空白字元。
\S 非空白字元。

Anchoring Metacharacters
Character 說明
^ 字串開頭

每一行開頭(任何 \n 之後)(在 /m 多列模式下)。
$ 字串結尾

每一行結尾(任何 \n 之前)(在 /m 多列模式下)。
\b word boundary(字詞邊界),介於 \w 與 \W 之間位置,以及字串開頭與結尾。
範例1:
var str = "xyz123";
str.match(/\bxy/); // 符合 xy
str.match(/\byz/); // 沒有符合
str.match(/z123\b/); // 符合 z123
str.match(/xyz12\b/); // 沒有符合
str.match(/\w\b/); // 符合 3
範例2:
var str = "xyz123\n";
console.log(str.match(/\w\b/)); // 符合 3
\B 非word boundary(非字詞邊界)
範例1:
var str = "xyz123";
str.match(/\Bxy/); // 沒有符合
str.match(/\Byz/); // 符合 yz
str.match(/z123\B/); // 沒有符合
str.match(/xyz12\B/); // 符合 xyz12
範例2:
var str = "xyz123\n";
str.match(/\w\B/); // 符合 x
str.match(/\B\w/); // 符合 y
(?=...) Positive lookahead
(?!...) Negative lookahead

Pattern Modifiers
modifiers 說明
i 不區分大小寫
m 多列模式
s 單列模式
(ECMA2018後支援,https://stackoverflow.com/questions/1979884/how-to-use-javascript-regex-over-multiple-lines)
g global match
找出所有符合的資料,而不是找到第一個符合的就停止。
範例:
var str = "xyz123xyz456";
str.match(/xyz[0-9]/); // 符合 xyz1
str.match(/xyz[0-9]/g); // 符合 xyz1 和 xyz4

其他
語法 說明
(...) 子樣式,並將符合子樣式的字串
儲存(記憶)於 \1、\2...與 $1、$2... 變數
\n 在樣式字串中,表示符合第 n 組記憶的字串。
$n 在替換字串中,表示符合第 n 組記憶的字串。
(?:...) 子樣式,但不將符合的字串儲存(記憶)起來。
...|... OR
* 0次以上 (貪多)
範例:
原字串:abbbcc
正規式:ab*
結果:abbb (貪多,以多為優先)
+ 1次以上
? 0次或1次
{n} 剛好n次
{n,} n次以上
{x,y} x次~y次
*? 0次或多次,以少為優先
範例:
原字串:abbbcc
正規式:ab*?
結果:a (不貪多,以少為優先)
+? 1次或多次,以少為優先
?? 0次或1次,以少為優先
{n,}? n次以上,以少為優先
{x,y}? x次~y次,以少為優先


JavaScript String 的樣式比對方法:
String 有四種比對方法,這四種比對方法都要傳入 pattern(比對樣式),
pattern 可以使用 /pattern/modifiersnew RegExp(pattern,modifiers) 的方式來產生。
  • search(pattern) 方法
    傳回符合 pattern 的第一個字元位置,若沒有符合的資料,則回傳 -1
    var str = "xyz";
    str.search(/xy/); // 0
    str.search(/yz/); // 1
    str.search(/ab/); // -1
  • replace(pattern, replacement) 方法
    找出符合 pattern 的字串,並用 replacement 取代。
    replacement 裡面可以使用 $n 語法來表示第 n 組記憶的字串。
    // 將第1個 , 用 # 取代
    "01,02,03,04,05".replace(/,/, '#'); // 01#02,03,04,05
    
    // 全部的 , 用 # 取代
    "01,02,03,04,05".replace(/,/g, '#'); // 01#02#03#04#05
    
    // 將第2個 , 用 # 取代 (replacement 使用到 $n 的技巧)
    "01,02,03,04,05".replace(/^([0-9]{2},[0-9]{2})(,)(.*)$/, '$1#$3'); // 01,02#03,04,05
  • match(pattern) 方法
    找出符合 pattern 的字串,找不到時回傳 null

    不在 g 模式下,找到時,回傳陣列,第 0 個元素是符合的字串,
    若有使用小括號,子樣式的記憶組,則會依序列在 第1、第2....個元素
    陣列還會有 index、input 兩個屬性
    index:符合的第一個字元位置
    input:原始字串
    var str = "abxyz123xyz456";
    var arr = str.match(/xy(z[0-9])[0-9]/); 
    arr[0]; // xyz12
    arr[1]; // xyz1
    arr["index"]; // 2
    arr["input"]; // abxyz123xyz456

    在 g 模式下,找到時,回傳陣列,第 0 個、第1個 .... 元素都是符合的字串,沒有包含使用小括號的子樣式記憶組。
    var str = "abxyz123xyz456";
    var arr = str.match(/xy(z[0-9])[0-9]/g);
    arr[0]; // xyz12
    arr[1]; // xyz45
  • split(pattern, limit)
    使用 pattern 來分割字串為陣列,最多分割為 limit 個。
    pattern 若有子樣式,會放在在每個符合字串的後面。
    var str = "a,b,c,d,e";
    str.split(/,/, 3); // ["a", "b", "c"]
    
    var str = "a#b#c";
    str.split(/(#)/); // ["a", "#", "b", "#", "c"]

JavaScript 的 RegExp 物件:
  • 建構式
    /pattern/modifiersnew RegExp(pattern,modifiers)
    使用 new RegExp,可以由變數組成的正規式字串產生 RegExp 物件
    例如:
    var pattern=/[0-9]{1,2}/g
    
    若數字 2 改由變數組成,則可用以下方式產生 RegExp 物件
    var v=2;
    var pattern = new RegExp("[0-9]{1," + v + "}", "g");
  • 屬性
    global:boolean 值, g 模式
    ignoreCase:boolean 值, i 模式
    lastIndex:數字,下一次要開始比對的字串索引位置
    multiline:boolean 值, m 模式
    source:產生此 RegExp 物件的 pattern
  • 方法
    exec(text):搜尋 text 是否有符合樣式的資料,回傳陣列(含符合字串和子樣式記憶組),失敗時回傳 null。
    var pattern = /xyz\w?/g;
    var str = "abcxyz123xyz456z";
    var arr;
    while (null !== (arr = pattern.exec(str)))
    {
        console.log(arr);
        /* 第一次迴圈執行結果
        arr[0]; // xyz1  
        arr.index; // 3
        arr.input; // abcxyz123xyz456z
        */
        
        /* 第一次迴圈執行結果
        arr[0]; // xyz4  
        arr.index; // 9
        arr.input; // abcxyz123xyz456z
        */ 
    }

    test(text):搜尋 text 是否有符合樣式的資料,回傳 boolean 值。
    var pattern = /xy/g;
    pattern.lastIndex; // 0
    
    pattern.test("xyzxyz"); // true
    pattern.lastIndex; // 2
    
    pattern.test("xyzxyz"); // true
    pattern.lastIndex; // 5
    
    pattern.test("xyz"); // false
    pattern.lastIndex; // 0
    
    pattern.test("xyz"); // true
    pattern.lastIndex; // 2

    註:exec(text)、test(text) 在 g 模式底下,後續的比對,都是從 lastIndex 開始(即使 text 是另一個字串)

參考:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions
http://www.w3schools.com/jsref/jsref_obj_regexp.asp
http://www.javascriptkit.com/javatutors/redev2.shtml
http://w3processing.com/index.php?subMenuId=224
http://www.referencedesigner.com/tutorials/jsre/jsre_17.php

沒有留言:

張貼留言