10-2

JavaScript 在第四版之後,針對通用表示法增加了數個字串方法,這些字串方法的用途很廣,可以列舉如下:

字串方法功能
string.search(re)通用式 re 在某個字串 string 出現的位置
string.match(re)從字串 string 抽取符合通用式 re 的子字串,並以字串陣列傳回
string.replace(re, newStr)將字串 string 符合通用式 re 的部分,代換為 newStr

使用通用表示法及上述的字串方法,我們對字串的處理能力大增,不但可以進行搜尋比對,還可以立刻修改字串(例如:即時修正表單資料),本節將說明這些功能。

若要尋找某個通用式在一個字串的第一次出現的位置,可用字串的 search 方法,例如:

Example(regExpSearch01.htm):

相關原始碼如下:

原始檔(regExpSearch01.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>通用式:搜尋並列出位置</h2>
<hr>

<script>
function regExpMatch(string, pattern, flag){
	var regexp = new RegExp(pattern, flag);
	var index = string.search(regexp);
	alert(index);
}
</script>
<center>
 字串:<input size=40 id=strId value="阿輝伯是李登輝,李炳輝是金門王的搭檔"><br>
通用式:<input size=40 id=patId value="李.輝"><br>
 選項:<input size=40 id=flagId value="g"><br>
<input type="button" value="顯示搜尋結果" onClick="regExpMatch(strId.value, patId.value, flagId.value)">
</center>

<hr>
</body>
</html>

其中 str.search(re) 將會傳回符合 re 的第一個位置(此例為 4)。若字串 str 不符合 re,則回傳值為 -1。若只是要判斷輸入字串是否符合某個通用式,也可以使用 re.test(str),這在上一節已經說明過了。

Hint
str.search(re) 只能用來搜尋某個通用式在一個字串的第一次出現的位置,所以在上述範例中,無論選項的輸入值為何,都只有一個搜尋結果。

使用字串的 match 方法,可在一個字串中,取出符合某個通用表示式的所有子字串,例如:

Example(regExpMatch01.htm):

相關原始碼如下:

原始檔(regExpMatch01.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>通用式:搜尋並列出比對到的字串</h2>
<hr>

<script>
function regExpMatch(string, pattern, flag){
	var regexp = new RegExp(pattern, flag);
	var matched = string.match(regexp);
	alert(matched);
}
</script>
<center>
 字串:<input size=40 id=strId value="阿輝伯是李登輝,李炳輝是金門王的搭檔"><br>
通用式:<input size=40 id=patId value="李.輝"><br>
 選項:<input size=40 id=flagId value="g"><br>
<input type="button" value="顯示搜尋結果" onClick="regExpMatch(strId.value, patId.value, flagId.value)">
</center>

<hr>
</body>
</html>

其中「.」可比對任何一個字元,而傳回的 matched 變數則是一個陣列,包含所比對到的字串。

善用通用表示式及字串的 replace 方法,就可以對字串進行任意修改。例如:

Example(regExpReplace01.htm):

相關原始碼如下:

原始檔(regExpReplace01.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>通用式:搜尋並代換</h2>
<hr>

<script>
function regExpReplace(strId, pat1id, pat2id, flagId){
	var regexp = new RegExp(pat1id.value, flagId.value);
	var str = strId.value;
	var newString = str.replace(regexp, pat2id.value);
	alert(newString);
}
</script>
<center>
 字串:<input size=40 id=strId value="我愛用通用式,通用式功能強大"><br>
通用式:<input size=40 id=pat1id value="通.式"><br>
新字串:<input size=40 id=pat2id value="正規式"><br>
 選項:<input size=40 id=flagId value=""><br>
<input type="button" value="顯示代換結果" onClick="regExpReplace(strId, pat1id, pat2id, flagId)">
</center>

<hr>
</body>
</html>

在上例中,字串的 replace 方法將符合通用式的第一部分代換成「正規式」,並將新字串傳回給變數 newString。若要將所有的「通用式」改成「正規式」,只需將選項改成「g」就可以了。

處理表單資料時,最常用的資料修正方式就是去除前後的空白。這種例行工作就可以由通用表示法及字串的 replace 方法來輕鬆完成。例如:

Example(regExpReplace02.htm):

在上例中,若按下「修正」,JavaScript 即會將所有的空白部分(含中文大五碼)刪除。程式碼如下:

原始檔(regExpReplace02.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>通用式:修正中文姓名</h2>
<hr>

<script>
function checkChineseName(uiControl) {
	uiControl.value = uiControl.value.replace(/[\s ]+/g, "");    // \s & 全形空白
}
</script>
中文大名:<input id=chineseName value=" 金     城   武 ">
<input type=button value="修正" onClick="checkChineseName(chineseName)">

<hr>
</body>
</html>

在上述範例中,[\s ] 是代表英文空白字元或大五碼的全形空白字元,因此 [\s ]+ 就是代表中文中可能出現的空白字串,而 replace(/[\s ]+/g, "") 則是將此類字串全部刪除,也就是代換為空字串。

Hint
上述範例有點畫蛇添足,下列通用式也可以達到同樣的效果:

/[\s ]/g

對於英文的輸入,我們通常要消除字頭及字尾的空白,並將句中的多個空白合成一個空格,例如:

Example(regExpReplace03.htm):

程式碼如下:

原始檔(regExpReplace03.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>通用式:修正英文姓名</h2>
<hr>

<script>
function checkEnglishName(uiControl) {
	var str = uiControl.value;
	str = str.replace(/^[\s ]+/g, "");	// 刪除頭部的空白字串
	str = str.replace(/[\s ]+$/g, "");	// 刪除尾部的空白字串
	str = str.replace(/[\s ]+/g, " ");	// 將其他空白字串代換成單一半形空格
	uiControl.value = str;
}
</script>
英文大名:<input id=englishName value="           Michael       Jordan ">
<input type=button value="修正" onClick="checkEnglishName(englishName)">

<hr>
</body>
</html>

我們可以使用 "|" 來代表「或」,因此在上述範例中,刪除頭部和尾部的空白字串,可以合成一個敘述,如下:

str = str.replace(/^[\s ]+|[\s ]+$/g, "");

如果在通用式使用重複字元時(例如「*」代表重複0次或多次,「+」代表重複至少1次等。),比對之後可能會出現兩種不同的結果,這兩種結果都滿足原來的通用式。此時我們必須知道通用式在進行比對時所採取的原則,才能得到符合我們期望的結果。一般而言,比對原則可以概述如下:

下面是一個範例:

Example(regExpGreedy01.htm):

在上述範例中,第一個通用式是採取預設的「貪心比對」,因此比對到的字串會是 batbetbitbotbut,此字串是在比對成功的情況下、最長的字串。而在第二個通用式中,我們在星號後面加了一個問號,代表採取「最小比對」,因此比對到的字串是 bat,此字串是在比對成功的情況下、最短的字串。此範例的程式碼如下:

原始檔(regExpGreedy01.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>通用式的「貪心比對」與「最小比對」</h2>
<hr>

<script>
str = "fred batbetbitbotbut barney"
document.write("str = "+str+"<br>");
document.write("貪心比對:<br>");
re = /b.*t/;
document.write("re = "+re+"<br>");
document.write("str.match(re) = "+str.match(re)+"<br>");
document.write("最小比對:<br>");
re = /b.*?t/;
document.write("re = "+re+"<br>");
document.write("str.match(re) = "+str.match(re)+"<br>");
</script>

<hr>
</body>
</html>

在使用「貪心比對」時,會採用「越左越貪」的原則,若要推翻此原則,可以適時使用問號,以採用「最小比對」,例如:

Example(regExpGreedy02.htm):

此範例的程式碼如下:

原始檔(regExpGreedy02.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>通用式的「越左越貪」比對方式</h2>
<hr>

<script>
str = "a xx b xxx b xxxx d";
document.write("str = "+str+"<br>");
document.write("越左越貪:<br>");
re = /a(.*)b(.*)d/;
document.write("re = "+re+"<br>");
found = str.match(re);
document.write("RegExp.$1 = "+RegExp.$1+", RegExp.$2 = "+RegExp.$2+"<br>");
document.write("推翻越左越貪:<br>");
re = /a(.*?)b(.*)d/;
document.write("re = "+re+"<br>");
found = str.match(re);
document.write("RegExp.$1 = "+RegExp.$1+", RegExp.$2 = "+RegExp.$2+"<br>");
</script>

<hr>
</body>
</html>

在上例中,我們在通用式中加了括號,符合括號中的比對條件者,將被設定至 RegExp.$1、RegExp.$2 等變數中,以便後續處理。 (為簡化起見,RegExp.$1 可以簡寫成 $1,RegExp.$2 可以簡寫成 $2,依此類推。)此外,在第一個通用式中,由於採取預設的「越左越貪」,所以 RegExp.$1 = "xx b xxx" 且 RegExp.$2 = "xxxx";但在第二個通用式中,由於我們適時使用了問號來進行「最小比對」,所以得到 RegExp.$1 = "xx" 且 RegExp.$2 = "xxx b xxxx"。

以下這個範例,利用 replace() 將一句英文中的前兩個字彙對調:

Example(regExpReplace04.htm):

程式碼如下:

原始檔(regExpReplace04.htm):(灰色區域按兩下即可拷貝)
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
</head>

<body>
<h2 align=center>通用式:對調兩個英文字</h2>
<hr>

<script>
function exchangeWord(id) {
	var regexp = /(\w+)\s+(\w+)/;
	var newString = id.innerHTML.replace(regexp, "$2 $1");
	alert("First matched word = " + RegExp.$1);
	alert("Second matched word = " + RegExp.$2);
	id.innerHTML = newString;
}
</script>
請點選下列文字以對調前兩個英文字:<p>
<div onClick='exchangeWord(this)'>we are the world!</div>

<hr>
</body>
</html>

以下這個範例,利用 replace() 在 onBlur 事件時,先修正文字欄位,再進行驗證:

Example(regExpReplace05.htm):

由於篇幅有限,在此不再列出此範例之原始碼。


JavaScript 程式設計與應用:用於網頁用戶端