2010年9月16日 星期四

Regular Expression (RegExp) in JavaScript


Regular Expression (以下簡稱 REGEX) 是以一組特定字元符號描述字串樣式規則的記述語法。簡單地說, REGEX 用於表達字元符號在字串中出現的規則。舉個例子說明,在 REGEX 中,字元 '^' 放在第一個位置表示字串開頭位置,當我寫下 ^A 的記述時,便表示必須是一個開頭為 A 的字串,如 Adam,才符合此一規則。這個表達規則通常稱為 pattern 。 ECMAScript/JavaScript 以內建的 RegExp Object 提供 REGEX 功能。See also: ECMA-262 15.10 - RegExp Objects





要產生一個 RegExp 個體有兩種方式。第一種是直接以斜線 (/) 包住 pattern ,例如 /^A/ 。注意不要再用單引號或雙引號包在斜線外圍,一但用了引號圍住,就只是一個 String 而非 RegExp 個體。 "/^A/" 就是錯誤寫法,這只是一個普通字串。第二種是向系統要求建立一個 RegExp 個體,即 new RegExp(pattern) ,引數 pattern 可以是一個字串也可以是另一個 RegExp 個體。第一種方法只能使用常值的 pattern ,我們不能用斜線包住一個變數或一個字串運算結果。如果 pattern 保存在變數之中,則必須使用第二種方式。




RegExp 個體提供兩個主要行為,即 exec() 和 test() 。 exec() 會對引數字串進行比對運算,並將匹配的字串內容記錄在陣列中回傳。而 test() 則僅僅測試引數字串是否符合規則,只回傳 truefalse 。此外,RegExp 個體也可以作為 String 個體的 match(), search(), replace(), split() 之引數。 String 的 match() 其實就是調用 RegExp 的 exec() ,兩者的結果相同。






ECMAScript/JavaScript 的 REGEX 規則是以 Perl 的規則為範本 (PHP 中稱為 PCRE 的內容) ,本文僅簡短說明幾個常見的字元意義。想了解更多用法者,請參看 Perl/PHP 的相關書籍,以及 ECMA-262 15.10 的內容。



  1. ^
    寫在 pattern 第一個位置時,表示其後一符號必須出現在字串開頭的位置。寫在 pattern 中間位置時則為否定之意,表示字串中不可有 ^ 之後一符號的內容。

  2. $
    寫在 pattern 最後一個位置時,表示其前一符號必須出現在字串尾端的位置。寫在 pattern 中時無特別意義。

  3. *
    表示字串中有 0 到無數個其前一符號的內容。

  4. +
    表示字串中有 1 到無數個其前一符號的內容。

  5. ?
    表示字串中有 0 到 1個其前一符號的內容。

  6. { }
    表示前一符號在字串中的重覆次數。例如 /A{2}/ 表示 'A' 重覆兩次 (即 'AA') ;/A{2,}/ 表示字串含有 2 到無數多個 'A' ;/A{2,5}/ 表示含有 2 到 5 個 'A' 。

  7. .
    表示一個任意字元。

  8. [ ]
    表示字串含有括號中任一字元的內容。可以 - 表示一組連續字元,例如 /[a-z]/, /[0-9]/ 。注意, [] 僅代表一個字元,例如 /[abc]/ 表示 'a' 或 'b' 或 'c' ,而不是 'abc' 。

  9. ( )
    表示一個 sub pattern ,符合 sub pattern 的字串內容會被存放在匹配陣列中,並依序指派數字代表此 sub pattern 。可以此數字在 pattern 的其他地方引用內容,例如 /The h([0-9]) means Title (\1)/ 表示第 1 個 sub pattern 是 0 到 9 的任一字元,而 \1 表示匹配的內容。故 'The h1 means Title 1', 'The h2 means Title 2' 到 'The h9 means Title 9' 符合規則。

  10. \
    表示轉義 (escaping) ,將其後的字元視為一般字元。例如要表示字串中含有 '/' 字元時,就必須寫作 /\//


  11. 「或」意,字串中含有 '' 之前一符號或後一符號的內容。例如 /image\.(jpgpng)/ 表示 'image.jpg' 或 'image.png' 。通常會用 () 括住 '' 的前後符號。

  12. \d
    表示任何一個數字,意同 [0-9] 。

  13. \D
    表示任何一個非數字,意同 [^0-9] 。

  14. \w
    表示任何一個字元與數字以及 '_' ,意同 [a-zA-Z0-9_] 。

  15. \W
    表示任何一個 \w 以外的字元。

  16. \s
    表示任何一個空白符號,包括 \t, \v 等。

  17. \S
    表示任何一個非空白符號。



Example 1.


1
2
3
4
5
6
7
8
9
10
11
/\d{4}-\d{2}-\d{2}/.test('2007-01-25'); // true
'2007-01-25'.match(/\d{4}-\d{2}-\d{2}/); // true
var datePart = '2007-01-25'.match(/(\d{4})-(\d{2})-(\d{2})/);
// datePart is ['2007-01-25', '2007', '01', '25']
var emailPart = /^(\w+)@([\w.]+)/.exec('rock@example.com');
// emailPart = ['rock@example.com', 'rock', 'example.com']
var words = 'How are you doing, john?'.split(/[\s,\?\.]+/);
// words = ['How', 'are', 'you', 'doing', 'john', '']



Example 2. 一個簡單的 REGEX 測試工具,可以立即回應輸入的字串與 pattern 是否相符






REGEX test form


"

此輸入框中輸入字串



/

此輸入框中輸入 REGEX 內容。前後不用加 (/)。









/[a-z]+/i


Match!


Abc


,





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<script type="text/javascript">
function r_test(regex, s) {
var p = document.getElementById('r_test');
var result = document.createTextNode(
regex.test(s)
? 'Match!'
: 'Not match!'
);
p.replaceChild(result, p.lastChild);
}
function r_exec(regex, s) {
var p = document.getElementById('r_exec');
var matches = regex.exec(s);
var result = document.createTextNode(
matches
? matches.toString()
: 'Not match!'
);
p.replaceChild(result, p.lastChild);
}
function s_split(regex, s) {
var p = document.getElementById('s_split');
var splits = s.split(regex);
var result = document.createTextNode(
splits
? splits.toString()
: 'Not match!'
);
p.replaceChild(result, p.lastChild);
}
function regexp_match() {
var p = document.getElementById('regex');
var inputString = document.getElementById('inputString').value;
var patternString = document.getElementById('patternString').value;
var regexFlags = document.getElementsByName('regexFlags');
var flags = '';
for (i = regexFlags.length - 1; i >= 0; --i) {
if (regexFlags[i].checked) {
flags += regexFlags[i].value;
}
}
var regex = new RegExp(patternString, flags);
p.replaceChild(document.createTextNode(regex.toString()), p.lastChild);
r_test(regex, inputString);
r_exec(regex, inputString);
s_split(regex, inputString);
}
</script>

轉載自http://cgi.blog.roodo.com/trackback/2670695

沒有留言:

張貼留言