Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1663371
  • 博文数量: 607
  • 博客积分: 10031
  • 博客等级: 上将
  • 技术积分: 6633
  • 用 户 组: 普通用户
  • 注册时间: 2006-03-30 17:41
文章分类

全部博文(607)

文章存档

2011年(2)

2010年(15)

2009年(58)

2008年(172)

2007年(211)

2006年(149)

我的朋友

分类: 系统运维

2006-07-14 14:21:07

 

第 12 章 String object

 作者: 伍新華 Email: ng-sun-wah@graduate.hku.hk

 

 


 String object 及 length property

 

 建立 String object

  String 是指文字, 可以是一個字母, 也可以是一串的文字 (字串/string), 在JavaScript, string 要放在 " "' ' 內, 瀏覽器就會當這字串是一個 object, 例如:

x = "Good Morning"
str = "Good Afternoon"

  "Good Morning" 或 "Good Afternoon" 就是 String object, 我們可以直接使用這 object, 也可用較簡單的變數名稱來代表這些 object, 例如這處的 xstr。假若數字是放在 " " 內, 數字就會當作文字來處理。

  我們也可用 new 這個 operator來變出一個 String object, 就如 第 8 章 說的 new Array( ), 例如:

x = new String("Good Morning")
str = new String("Good Afternoon")

  我們一般不使用這較複雜的方法。

 

 String 的 length property

  String 內的字元數目就是 length property, 使用 stringName.length 就可讀取這數值。

練習-92 String object 及 length property

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:



2. 網頁開啟後, 你應見到以下兩句:

"Good Morning" has 12 characters.
"Good Afternoon" has 14 characters.

 

  你可看到 x 除了是一個變數, 用來代表 Good Morning, 也是一個 String object, 這 object 有 length 的 property, 使用 stringName.length 這方式, 就可顯示這字串內的字母數目。這例子的 x.length, 就是 x 內的字母數目。

 

  在以上例子, 假若用這寫法:

document.write("\"Good Morning\" has " + "Good Morning".length
+ "
characters.

" )
document.write("\
"Good Afternoon\" has " +"Good Afternoon".length
+ "
characters. " )

  效果也是一樣, 所以這寫法: "Good Morning".length , 在 " " 內的文字就可當作一個 String object 來看待。

 

  在 第 13 章 說到 validation (驗証), 其中一個方法是用 stringName. length 來檢查電話號碼是否等於8個位的數字, 請看以下例子。

練習-93 檢查電話號碼是否 8 個位數字

  在這示範, 你看到一個文字框, 你試輸入 8 個位及不是 8 個位的數字, 看各有什麼反應。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:



請填入你的電話號碼:
tx size=10 >

 

2. 網頁開啟後, 請試驗這三項操作, 看有什麼反應: (a) 不輸入任何文字就按 [確定],  (b) 輸入不是 8 個位的數字, 然後按 [確定],  (c) 輸入 8 個位數字然後按 [確定]

  這例子中的 document.fm.tx.value.length 是在文字框中字母或數字的數目, 例如 23256888, document.fm.tx.value.length 就會是 8。

 

 String 的陣列

  當我們設定一個 string, 這 string 內的字元就自動組成一個陣列, 我們利用一般的陣列方法, 就可指定這字串內某一個字元, 例如以下設定:

str = "Good Morning"
document.write( "
The 6th letter of \"" + str + "\" is " + str[5] )

  這會顯示這句:  

  留意陣列的排序是從 0 開始, 也包括空格字元。這陣列只在 Netscape 有效, IE 無效, 但可使用隨後說的一些 method 來代替。

 

 


 產生文字格式的 method

  在 HTML 中, 我們可以使用一些標籤 (tag) 來控制文字的格式, 例如大小、顏色、粗體、斜體等等。在 JavaScript, 若我們使用 document.write( ) 來顯示文字, 可使用一些 method 來控制顯示文字的格式, 語法是: stringName.method( )

  留意這些語法只在 document.write( ) 中有效, 在一般 JavaScript 中不能使用。

練習-94 使用 JavaScript 產生文字格式

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:



2. 網頁開啟後, 你應見到以下兩句:

The first line is Good Morning
The second line is Good Morning

 

  若有多個格式要加在字串上, 可用這語法:

stringName.method1( ).method2( )

例如: str.big( ).italics( ).fontcolor(red)

  這會產生大一級字、斜體、紅色的效果。

 

  在實際使用時, 我們也可使用 HTML 的標籤, 這可能會較方便, 例如以下寫法也會產生大一級字、斜體、紅色的效果

document.write("The first line is 1 color=red> "
+
str + "
" )

 

  使用 HTML 標籤, 留意要將標籤放在 " " 內。

  以下是有關文字格式的 method:

 

stringName.big( ) 這產生大一級字。
stringName.blink( ) 這產生閃動字。
stringName.bold( ) 這產生粗體字。
stringName.fixed( ) 這產生固定字寬字體。
stringName.italics( ) 這產生斜體字。
stringName.small( ) 這產生細一級字。
stringName.strike( ) 這在字中加上刪除線。
stringName.sub( ) 這產生下標字。
stringName.sup( ) 這產生上標字。

 

stringName.fontcolor( )

  這是指定字的顏色, 顏色名稱放在 ( ) 內, 也可使用 RGB 的 hex 數字, 例如:

str = "Good Morning"
document.write(
str.fontcolor("darkviolet") )

  顯示的 Good Morning 就會是深紫色, 留意顏色名稱要放在 " " 內, 否則瀏覽器會將這名稱看作是變數, 而因這變數還未定義, 所以會有訊息告訴你這名稱是 undefined。

  顏色指示也可寫成: document.write(str.fontcolor("#9400D3") ), 有關各顏色的名稱及 hex 數字, 請看 附錄-8

 

stringName.fontsize( )

  這是指定字的大小, 由最小的 1 級至最大的 7 級, 數字要放在 ( ) 內, 例如以下的 fontsize(6) 會產生 6 級大的字。

str = "Good Morning"
document.write(
str.fontsize(6) )

 

stringName.toLowerCase( )

  這是將字變為全小寫, 例如以下設定會顯示: good morning, 這項功能也可在 alert 對話盒中使用。

str = "Good Morning"
document.write(
str.toLowerCase( ) )

 

stringName.toUpperCase( )

  這是將字變為全大寫, 例如以下設定會顯示: GOOD MORNING, 這項功能也可在 alert 對話盒中使用。

str = "Good Morning"
document.write(
str.toUpperCase( ) )

 

 


 String 內的文字控制

 

 stringName.charAt(index)

  String內的字元 (character) 是一個陣列, 排序位置是為 index, 由 0 開始從左至右排下去, 包括空格字元, 例如

 

  要傳回某個 index 的字元, 可使用以下語法:

stringName.charAt(index)

 

練習-95 利用 charAt( ) 傳回某個位置的字元

  這示範先造出一個名為 str 的自訂字串, 然後利用 charAt( ) 來傳回在 0、5 及最後的字元。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:



2. 開啟這網頁後, 你應見到以下三句:

The 1st letter is: G
The 6th letter is: M
The last letter is: g

  Index 的排序是從 0 開始, 所以 charAt(0) 就是 G, charAt(5) 是第 6 個字母, 即是 M, 最後一個字元是 str.length-1 , 即是 g。

 

練習-96 檢查電郵地址中的 @ 字元

  在 form 的操作, 有時需要設定一個文字框讓觀看者輸入電郵地址, 而電郵地址一定會有 @ 這字元, 我們可以利用 charAt( ) 來檢查觀看者輸入的電郵地址是否有這字元, 如果沒有就可叫他重新輸入。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:


請填入你的電郵地址:
tx >


2. 開啟這網頁後, 你應見到一個文字框, 請你依隨後的解說, 輸入一個電郵地址及將 @ 的字符放在不同位置, 或略去這字符, 看有什麼反應

 

1. 因電郵地址一般不會少於 8 個字元, 所以 if (x.length < 8) 首先檢查輸入的文字是否少於 8 個字元, 是則發出警告及終止隨後的程序 (return)。

2. 第二項設定是: if (x.charAt(0)=="@" || x.charAt(1)=="@" . . . , 這是檢查第1、2、尾、尾2、尾3、尾4 這六個位置是否有 @ 這字元, 有則發出警告及終止隨後的程序。例如以下的地址:

  

3. 跟住是設定 flag 這變數 (請看 10.3 的一節), 初始值是 0。

4. 隨後的 for ( i = 2 ; i < (x.length - 4) ; i++ ) 是檢查第 3 至尾 5 這列位置是否有 @ 這字元, 這處使用 flag+=1作記錄, 如果這位置內有一個 @ , flag 就變為 1, 這是正常, 若無則 flag 會是 0, 若有兩個或以上的 @ , flag 就變為大過 1, 這兩個情況都會作錯誤來處理。

 

 stringName.charCodeAt(index)

  這 method 與 charAt( ) 相似, 但傳回的不是字元, 而是該字元的 ASCII 編碼, 有關這編碼, 請看 附錄-10。例如以下兩句:

a="happy".charAt(0)
b="happy".charCodeAt(0)

  在第一句, a 會是 h , 因為 charAt(0) 是傳回 happy 第一個字母 (index=0), 第二句則是傳回第一個字母的 ASCII 編碼, 所以 b 會是 104。

  在 練習-93 說過如何檢查輸入的電話號碼是否 8 個位數字, 利用 charCodeAt( ), 我們可以進一步檢查觀看者是否錯誤將一個字母混在電話號碼中, 若有的就會有對話盒告訴他改正, 請看以下例子。

 

練習-97 檢查電話號碼中是否有英文字母

  在 附錄-10, 你可看到數目字 0 至 9 的編碼是 48 至 57, 以下例子的檢查原理是看文字框中輸入的每一個字元是否在 48 至 57 的範圍, 若不是就表示有非數字在內, 這會引出一個 alert 對話盒通知觀看者。考慮到有人可能會在號碼中加進一個空格 (編碼是 32), 所以這檢查也接受號碼中有空格, 這例子也檢查輸入的電話號碼是否八個位數字。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:


請輸入電話號碼:
tx size=10>

2. 網頁中有一個文字框, 請你試驗以下四項輸入, 然後按 [確定], 看有什麼效果: (1) 不輸入任何資料, (2) 輸入數字, 內裡加上一個字母, (3) 輸入 8 個數字 (內裡加入或不加入空格), (4) 輸入多過或少過 8 個數字

3. 請你將這檔案複製去硬碟, 在檔案中刪去以下一句:

if (x.charCodeAt(i) == 32 ) continue

  在輸入的電話號碼中加進空格, 看有什麼效果。

 

  在 6.10 的一節說過 continue 的用途, 這例子加上這 statement, 當檢查到編碼是 32 的字元 (空格字元), 就會跳過該迴圈, 所以這檢查不理會空格字元。

  for (i=0; i <= (x.length-1); i++ ) 這一句是逐個字元來檢查, 以下一句是看每個字元編碼是否在 48 及 57 這範圍之外:

if (x.charCodeAt(i) < 48 || x.charCodeAt(i) > 57 )

  若這是 TRUE (即是字元編碼小於 48 或大過 57) , 就會有對話盒出現, 同時用return來終止隨後的操作。

 

 stringName.concat( )

  這是用來連結兩個字串, 有這語法:

x=string1.concat(string2)

  這將 string2 併在 string1 之後, 並以 x 代表新的字串, string1string2 不變, 例如以下網頁會顯示: Good Morning. What a nice day!



  我們也可用 + 這個 concatenation operator (文字連結器), 例如:

document.write( a + b )

 

 String.fromCharCode( )

  這是用來將 ASCII 編碼變為字元, 例如 65 變為 A, 66 變為 B, 67 變為 C 等等, 有以下語法:

String.fromCharCode(number1, number2, . . . )

  fromCharCode( ) 是一個固定的 method, 屬於 JavaScript 的 String object, 不可用於自訂的 string, 例如 str.fromCharCode(65) 是錯誤的語法。

  例如以下網頁:



  這會顯示 ABCDE 這五個字元。

  在前面的一段說到用 charCodeAt( ) 可傳回一個字元的 ASCII 編碼, 我們使用 String.fromCharCode( ) 就可將這編碼變為字母。

 

 stringName.indexOf( )

  indexOf( ) 是用來傳回一個或一組字元 (是為 value) 首次在一個字串中出現的排序位置, 有以下語法:

str.indexOf( "searchValue", fromIndex)

  str 是代表一個字串, searchValue 是要尋找的 value, 要分大小寫 (例如 Good 不能寫成 good), fromIndex 是指定從某個位置開始尋找, 若沒有這參數就是從 0 位置開始。(這處全部排序都是從 0 開始。)

  找到第一個 value 後, 就傳回這 value 的排序位置, 若找不到就傳回 -1

  例如以下兩句:

x="Good Morning. What a nice day ! "
document.write(
x.indexOf( "ing", 5 ) )

  這會顯示: 9 , 這 9 字是從 0 開始計算, 而且包括空格, 即是 "ing" 是在這字串的第 10 個位置開始。

 

  若使用以下的一句:

x="Good Morning. What a nice day ! "
document.write(
x.indexOf( "o" ) )

  這字串中有多個 o 字, indexOf( ) 是傳回第一個 o 字的位置, 所以以上兩句會顯示 1 字 (即是第 2 個位置)。

  在 練習-96, 你看到如何利用 charAt( ) 來檢查電郵地址中的 @ 字元, 我們也可以利用 indexOf(@) 來檢查, 請看以下例子。

 

練習-98 檢查電郵地址中的 @ 字元

  在這例子, 我們利用 indexOf(@) 來檢查電郵地址中 @ 字符的位置, 若沒有這字元, 或是這字元在第 1、2、尾、尾2、尾3、尾4 都看成是錯誤。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:


請填入你的電郵地址:
tx >

2. 開啟這網頁後, 你應見到一個文字框, 請你依 練習-96 的解說, 輸入一個電郵地址及將 @ 的字符放在不同位置, 或略去這字符, 或加進兩個 @ 字符, 看有什麼反應

 

1. 這例子首先使用 if(y == -1 ) 來看輸入的地址是否缺少了 @ 字元。

2. 若上句是 FALSE, 即是文字中有 @ 的字元, 就利用 if (y <= 2 || z >= x.length - 5 ) 來檢查這字元是否在 0、1、尾、尾2、尾3、尾4 的位置, 若是就算作錯誤。

3. 這例子同時也使用 lastIndexOf(@) 來看最後一個 @ 的出現位置, 這就是 z , 若上句是 FALSE, 就檢查是否 y==z, 若這是 TRUE, 即是文字中只有一個 @ , 這是正常, 若是 FALSE, 表示文字中有兩個 @ , 這看成是錯誤。

 

 複式 if...else statement

  在上個例子, 筆者使用了三個 if...else statements, 第二個放在第一個之內, 第三個放在第二個之內, 如下:

圖 12-1 複式的 if...else statements

 

  這類複式 statement 每使用一次 if...else, 就可排除一個可能性, 到最後必會得到一個最後反應。

  我們編寫程式經常都要用到這類複式 statement, 你開始使用時, 可能會感到迷惑, 但熟習後就會覺得好用了。

  留意上圖中的第二個 if...else statement是放在前個 else之內, 所以兩個 statement 是相連的, 假若分兩個獨立的 statement 來寫, 會有何不同 ? 請看以下寫法:

圖 12-2 獨立的 if...else statement

 

  使用這寫法, 當第二個檢查結果是 TRUE 時, 我們是不知第一個檢查結果是TRUE 或 FALSE。使用前個寫法, 當第二個檢查結果是 TRUE 時, 我們知道第一個檢查結果必是 FALSE。

  假若從檢查的範圍來看, 圖12-1 的第一、二個檢查有以下範圍:

 

  使用複式 if...else, 每一個 if...else 都會縮窄隨後的一個 if...else 的檢查範圍。使用獨立的 if...else , 會有以下分別:

  第二個 if...else 的檢查項目可能與第一個不同, 但檢查的範圍則是一樣。

 

 stringName.lastIndexOf( )

  這與 indexOf( ) 相似, 但傳回的是字串中最後一個找到的 value, 而不是第一個, 例如以下兩句:

x="Good Morning. What a nice day ! "
document.write(
x.lastIndexOf( "o" ) )

  這字串中有多個 o 字, lastIndexOf( ) 是傳回最後一個 o 字的位置, 所以以上兩句會顯示 6 字 (即是第 7 個位置)。

 

 stringName.slice( )

  這是用來抽取一個字串某部份, 變成另一個新字串, 有以下語法:

str.slice(開始位置,停止位置)

  這處的 str 是有關的字串, "停止位置" 是結束的位置, 但不包括這位置的字元, 若沒有這參數, 就是抽取至尾, 排序是以 0 來開始, 例如:

  這兩句會傳回: Hello, Smith j

 

  假若第二個參數使用負數, 就是從尾向左數起, 例如以下的 -5 就是抽取至尾 5的字, 但抽取的部份不包括這字, 所以以下兩句會傳回 Hello, Smith j

 

 stringName.substr( )

  這是用來抽取一個字串某個長度的字元, 變成另一個新字串, 有以下語法: (留意這 method 名稱是 substr( ), 不是 subStr( )。)

str.substr(開始位置,字元數目)

  這處的 str 是有關的字串, 若沒有指定 "字元數目" 就是抽取至尾, 排序是以 0 來開始, 例如以下兩句會傳回: Hello, Smith j

 

 stringName.substring( )

  這項功能及語法和 slice( ) 相同, 例如以下兩句會傳回: Hello, Smith j

  留意這 method 名稱是 substring( ), 不是 subString( )。

 

 match( )、search( ) 及 replace( )

  這三個功能主要是與 regular expression合併使用, 請看下一節有關的詳細使用方式。

  我們也可在一般的 JavaScript 使用這三項功能, 請看以下例子。

 

stringName.match( ) 的使用:

  這是在一句中找某個字母或文字, 使用以下語法:

str.match("目標字")

  str 是有關的字串, 目標字是要在這字串內尋找的文字, 找到就傳回目標字, 找不到就傳回 null 這一個字, 請看這例子:



  以上的 script 會在 alert 對話盒顯示 red 這個找到的字, 假若將上述的 scritp 改為以下內容:

  alert 對話盒會顯示 null 這字, 表示在 x 內沒有 red 這個字。

 

stringName.search( ) 的使用:

  這是在一句中找某個字母或文字, 使用以下語法:

str.search("目標字")

  str 是有關的字串, 目標字是要在這字串內尋找的文字, 找到就傳回目標字的排序位置, 找不到就傳回 -1 , 請看這例子:



  以上的 script 會在 alert 對話盒顯示 28 , 表示 red 字是在 x 這句中的第 28 個位置 (從 0 開始計算), 若找不到就傳回 -1。

 

stringName.replace( ) 的使用:

  這功能有這語法: str.replace("目標字","代替字")

  str 是有關的字串, "目標字" 是要在這字串內尋找的文字, 找到就用 "代替字" 來取代, 並傳回新的字串, 原有字串不變, 請看這例子:



  以上的 script 是在 x 這句內以 violet 取代 red, alert 對話盒顯示這句: My favourite colors include violet, yellow and blue.。, 若 x 內沒有目標字就不會被改變。

 

 


 Regular expression

 

1. Regular expression 的用途

  Regular expression 是 JavaScript 中的一種文字方程式, 利用一些代號來代表某些文字組合, 例如 \d 代表數目字元, \D 代表非數目字元, \w 代表一個英文字, \s 代表空格, 等等, 我們利用這些代號組合, 就可在一個字串 (string) 中找到是否有符合 (match) 我們指定的某個字元組合 (這些字元組合是為 pattern)。

  Regular expression 是在 Netscape-4 新增的功能, 使用 Perl 語言的習慣, Perl 是Internet 中普遍使用的程式語言, 強項是在文字處理方面, 所以 regular expression 最適用於 form 內有關文字及數字的 validation, 一些複習檢查, 使用 regular expression 就可簡易造到, 若使用 JavaScript 的 charAt( )charCodeAt( ) 等來檢查, 未必能做到, 就算做到, 程式會很長及很複雜, 若有大量檢查就會使到網頁很長, 浪費傳送時間。

  Regular expression一般是與 String object 的 match( )search( ) replace( ) 合用, 請先看以下例子。

 

練習-99 使用 regular expression 來驗証電話號碼

  在 第 13章, 你會看到如何使用一般的 JavaScript 來作 validation, 例如我們設定一個文字框, 要求觀看者輸入電話號碼, 要使用類似以下的國際格式: +852 12345678, 這格式有以下規定:

1. 第一個字元一定是 + 。
2. + 後有地區編號的三個數目字, 隨後必需有一個空格。
3. 再隨後應有 8 個數目字, 第 4 個數字後可以有一個空格。
4. 整個號碼不應有英文字母。

  若用一般的 JavaScript 來檢查觀看者輸入的電話號碼是否符合這格式, 程式會很長及很複雜, 用r egular expression 一般用兩行就可完成指定這格式的部份。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:


請輸入你的電話號碼, 要用國際格式, 例如 +852 12345678 :

fm>
tx onChange="checkIt( )">

2. 網頁開啟後, 你會見到一個文字框, 請你輸入合規格的電話號碼, 然後用滑鼠在文字框外按一下 (啟動 onChange), 看有什麼反應。另在這號碼前後加上空格字元, 看是否影響到檢查。

3. 跟著依前面說的四個規格, 輸入不符合這規格的電話號碼, 例如輸入 7 個或 9 個數字, 或混入英文字母, 或沒有 + 在前, 等等, 看這 script 是否能檢查出來

 

  在這例子, regular expression 是以下的一句:

/^\s*\x2b\d\d\d\s+\d{4}\s*\d{4}\s*$/

  我們可以直接使用這一句, 但一般是用一個變數來代表這句, 習慣是使用 re 這變數名稱。

  跟著的 document.fm.tx.value.search(re) 是在文字框輸入的字串中找尋是否有 re 所代表的 pattern, 找到就傳回 re 在字串的排序位置, 找不到就傳回 -1 , 這結果用 x 來代表, 隨後的 if( x == -1 ) 就是檢查是否找到 re 代表的字串。

 

2. Regular expression 的設定

  設定一個 regular expression 有以下兩個語法,

   /pattern/flag
或  new RegExp("pattern", "flag")

  我們一般會用 re (自訂的變數名稱) 來代表一個 regular expression, 所以會有以下的 statements:

   re=/pattern/flag
或  re=new RegExp("pattern", "flag")

  這處的 pattern 是指文字方程式, flag 可以是 gi gi , 隨後會有解釋。例如pattern 是要檢查一句文字中是否有 apple 或 orange 兩個字, 不理會大小寫, 有以下語法:

re=/apple|orange/gi

  這處要留意, 除非真的要找一個空格, 否則不要在 regular expression 內加上空格, 請看以下例子:

re=/on/   這是找 on 兩個字母, 包括 on、don't、pond 等等。
re=/ on/ 這是找前面有空格的 on, 即是三個字符, 包括 ononce、only等等, 不包括 don't、pond 等等。

 

3. match(re) 的使用

  match( ) String 的一個 method, 與 re 合用, 有這語法:

x = str.match(re)

  這 str 代表我們設定或在文字框輸入的字串, re 是一個 regular expression, 這語法是要在 str 這字串中尋找是否符合 re 的文字, 若有的就傳回這文字及以 x 這變數來代表, 若無就傳回 null 字。

 

練習-100 match( ) 與 regular expression 的合併使用

  這網頁沒有實際用途, 只是讓你了解 match( ) 及 regular expression 如何合併使用, 在下個練習才示範 match( ) 的實際用途。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:


fm>
tx size=50 onChange="checkIt( )" >

2. 今次的 regular expression 有這設定: re=/apple|orange/gi , 這是尋找 apple 或 orange 這兩個字, 請你在文字框輸入以下一句:

This is an apple and that is an orange.

3. 輸入完畢, 用滑鼠在文字框外按一下, 就會出現以下對話盒:

4. 請你輸入 orange apple 或a pples oranges apple orange 等字, 看傳回什麼資料。

5. 請你再輸入一句文字, 內裡沒有 apple 及 orange 這兩個字, 看對話盒會出現什麼文字。(應該有 null 這字。)

 

  請看這句: x = document.fm.tx.value.match(re), 這是利用 match( )來在文字框的字串 (document.fm.tx.value) 中找 re 代表的文字, 若有符合的就將文字複製及以 x 來代表, 所以隨後的 alert(x) 會顯示找到的文字, 若找不到就傳回 null 這一個字。

  在試用 regular expression 時, 你可用這處的方法, 在文字框輸入文字來看 re 中的設定否正確, 然後用 alert 對話盒來顯示結果。

 

使用 global match:

1. 留意今次例子的 re=/apple|orange/gi , 這句之後有 g 的操作指示, g代表 global match, 即是尋找全部文字, 符合的會全部列出, 顯示時用 , 來分隔, 若不作這指定, 找到第一個字後就不再找下去。

2. 若在上述例子作這設定: re/apple|orange/i , 找到 apple 這字後, 就不再找下去, 所以對話盒中只會顯示 apple 一個字。

  例如在文字框輸入以下一句:

No money, no home, but NOT desperate and nothing to worry.

若使用 re=/no/i 會傳回一個 No 字 (第一個找到的字)。
若使用 re=/no/gi 會傳回 No,no,NO,no 四個字 (全部找到的字)。

  留意句子後方的 NOT 及 nothing 兩個字, 我們要找的是 no 這兩個字母, 這也包括一個字內的字母。若是指定不要字內的字母, 就要用 /\bno\b/gi , \b 代表字與字間的分隔, 所以會傳回 No,no 這結果。

 

使用 ignore case:

  前段例子的 re=/no/gi , 這句之後有 i 的操作指示, i 代表 ignore case, 即是不理會文字的大小寫, 以這句為例:

No money, no home, but NOT desperate and nothing to worry.

若使用 re=/no/g 會傳回 no,no 兩個字。
若使用 re=/No/g 會傳回 No
若使用 re=/NO/g 會傳回 NO
若使用 re=/no/gi 會傳回 No,no,NO,no

  若不加上 i 的指示, 尋找的字會分大小寫, 若指定找 no, 就不包括 No 或 NO。

 

  你在上個練習明白了 match( ) 的操作方式, 就可看看如何將這功能運用於實際用途。

 

練習-101 用 match(re) 檢查觀看者輸入的文字

  這例子的網頁在開啟後, 會顯示一幅圖片, 內有兩個生果 , 另有一個文字框要求觀看者輸入這兩個生果的英文名稱, 然後有一個 script 檢查觀看者輸入的文字, 若兩個字都正確, 就會有子視窗出現顯示讚賞的句子, 若一個或兩個字不正確, 就會有對話盒要求觀看者再試, 試三次都失敗就會給觀看者答案。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:


fruit.gif>
Please give the names of these two fruits and press


tx size=40>

2. 網頁開啟後, 你應見到以下的圖案及文字框:

3. 請你在文字框輸入正確的名稱, 看有什麼反應, regular expression 的特點是能在一段文字中抽出要檢查的文字, 例如觀看者輸入 one apple and three bananas, 這處的match(re1) 會找到 apple 這字, match(re2) 會找到 banana 這字。

4. 請你輸入錯誤的名稱三次, 看有什麼反應

 

1. 在這網頁的

  在對話盒中會出現一個 8 個字, 這表示 Blue 字在這句中是第 8 個字母 (留意: 排序由 0 開始)。

  在這句: re=/blue/i , 這 i 字表示不理會大小寫, 若沒有這 i 字, 例如 re=/blue/ , 就會傳回 -1 , 表示找不到符合的字。

  search( )match( ) 不同的是找到第一個字, 就不會找下去, 所以 g 這個操作參數在 search( ) 沒有作用, 例如:

  這處的 re=/blue|red/i 是找 blue 或 red, 不理會大小寫, 所以會找到 Red 這個字, 對話盒出現一個 0 字, 表示找到的字的排序位置是 0。

 

5. replace(re) 的使用

  replace( ) 是將找到的字轉為另一個指定的字或字串, 有以下語法:

str.replace(re, "newSubStr")

  str 代表被找的字串, re 是要尋找的文字, newSubstr 是用來代替被找到的文字, 依照慣例, 若是文字就要放在 " " 內, 變數則不需要, 請看以下例子。

練習-102 用 replace(re) 來轉換字串內某些文字

  這例子的網頁有一個文字框, 內有一句文字及一個按鈕, 你按這按鈕, 這句文字的 Red 字變為 Blue, red 變為 blue。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:


tx size=50
value="
Red shoes with a red jean will make your eyes red." >




2. 網頁開啟後, 你會見到以下文字框及文字:

  請你按 [Change] 的按鈕, 看有什麼反應

 

  在使用 replace( ) 時, 要留意大小寫的問題, 若你指定找 /red/gi 及用 blue 來代替, 這是不分大小寫, 所以也會找到 Red 這個字及用 blue 來代替, 一句中開首的 Red 不會變成 Blue, 而是變成 blue, 這引致文法上的錯誤。

 

6. Regular expression的代號

  Regular expression 的用途是讓我們放下一些代號, 然後使用 match(re) 等功能來找符合這代號所代表的文字。

  這些代號的字母有 \ 在前, 符號則沒有, 例如 \w 代表任何數目或字母, \b 代表字間的分隔符號, + 代表前個字符出現最少一次 (這是符號, 所以沒有 \ 在前), 例如 re=/\bm\w+/gi 有以下含意:

1. 有關 re=/ /gi 的意義, 請看前面解釋。
2. / 後的 \b 是一個代號, 代表字與字之間的分隔, 例如空格, 句號, 逗號等等。
3. 跟著的 m 字表示要找一個 m (或 M) 的字母。
4. m 後的 \w 是一個代號, 表示 m 後的是字母、數目字或 _ 字符, \w+ 表示這字符最少出現一次, 所以 \bm\w+ 是表示任何以 m 字為首的字, 例如 merry、moon 等等。

  這處要留意 \bm\w+ m\w+ 的分別, 前者要找的是以 m 為首的字, 例如 Wish you a merry Xmas 這句, 若用 /\bm\w+/gi 為尋找依據, 會找到 merry 這個字, 不包括Xmas 內的 mas, 若用 /m\w+/gi , 會找到 merry,mas 這兩個字。

練習-103 用代號來尋找合規律的字

  這例子的網頁有一個array, 內有一列人名, 你看到如何利用 regular expression 的方法來列出以 M 字為首的人名。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:



2. 網頁開啟後, 你會見到 兩列名單, 第一列是全部名單, 第二列是利用re=/\bm\w+/gi 找到的以 M 字為首的字。

3. 請你將以上網頁中的 re=/\bm\w+/gi 改為 re=/m\w+/gi , 看找到的有什麼文字。

 

1. 在這例子, 人名是以一個 array 的方式來存放, 所以要先用 toString( ) 變為一般的文字字串, 才能在 match( ) 中使用。

  變為字串後, 名稱間以 , 來分隔, 例如 Peter,Mary,John , 留意名稱間是沒有空格的, 筆者使用 replace( /,/g, ", " ) 在每個逗號後加一個空格, 就變成 Peter, Mary, John, . . . 。

2. 這處的 re=/\bm\w+/gi 在前面已解釋過, Mnames=names.match(re) 是將 names 內以 m 字為首的字抽出來, 並變成一個名為 Mnames 的陣列, 筆者將這陣列用 toString( ) 變成文字字串, 及再用 replace( /,/g, ", " ) 在逗號之後加上一個空格。

 

Regular expression 的代號:

  Regular expression 有以下二十多個代號:

\ 代表隨後的字元是代號, 例如 /d/ 符合 d 字元, /\d/ 符合任何數目字。
^ 代表一句的開頭, 例如 /^x/ 符合 xyz 的 x, 但不符合 wxyz 的 x。
$ 代表一句的尾, 例如 /c$/ 符合 abc 的 c, 但不符合 abcd 的 c。
* 代表前方的字元出現 0 或多次, 例如 /abc*/ 符合 ab, abc, abcc, abccc 等等。
+ 代表前方的字元出現 1 或多次, 例如 /abc*/ 符合 abc, abcc, abccc 。
? 代表前方的字元出現 0 或 1 次, 例如 /abc*/ 符合 ab 或 abc。
. 代表任何一個字元, 例如 /.r/ 符合 ar, br, cr 等等。
(a) 代表 a 及記下這元字, 例如 /(blue)/ 符合 blue color 內的 blue 字, 並記下這blue 字, 請看隨後 $1...$9 的一段中的解釋。
x|y 代表 x 或 y , 例如 /blue|red/ 符合 blue car 的 blue 及 red car 的 red。
{n} n 是個正數, 代表前個位置的字元出現的次數, 例如 /x{3}/ 是代表 3 個 x 字。
{n,} n 是個正數, 代表前個位置的字元出現最少的次數, 例如 /x{3,}/ 是代表 3 個或以上的 x 字。
{n,m} n 及 m 是正數, 代表前個位置的字元出現最少 n 次, 最多 m 次數, 例如 /x{3,8}/ 是代表 3 至 8 個的 x 字。
[xyz] 這是一組字元, 內裡任何一個字元皆合, 例如 /[pqr]/ 是符合 p、q 或 r, 但不符合 s 及 t。用 hyphen可指定一個範圍, 例如 /[0-9]/ 是代表任何數目字, /[a-e]/ 是代表 a 至 e 的字元。
[^xyz] 這是一組相反字元, 內裡任何一個字元皆不合, 例如 /[^abc]/ 是符合任何字元除了 a、b 及 c, /[^a-z]/ 是不符合任何英文字母。
[\b] 代表 backspace (退格鍵)。
\b 代表分隔兩字間的字元 (word boundary), 例如空格及 = ( / 等符號, 例如 /\bg/ 符合 .g =g %g ,g (g 等等, 也符合 so good 的 g 字或一句之首的 g 字, 但不符合 begin 或 again 的 g 字。
\B 代表非分隔字元, 即是代表字母或數字, 例如 /\Bst\/ 可代表 1st 或 paste 的 st, 但不代表 street 的 st。
\cX X 代表任何控制字元 (control character), 例如 /\cM/ 代表 control-M, 即是回位字元 (carriage return)。
\d 代表任何數目字, 即是 0-9, 例如 /\d\d/ 代表兩個數目字。
\D 代表任何非數目字, 即是英文字母及標點符號。
\f 代表 form-feed (即是分頁)。
\n 代表 line-feed (即是分行)。
\r 代表 carriage return (即是回位)。
\s 代表任何空位, 包括 space(空格)、tab(跳格)、form feed (分頁) 及 line feed (分行), 即是空格及 [\f\n\r\t\v] 例如 /o\s\w*/ 代表 too good 的 o good。
\S 代表任何非空位字元, 即不是 \s。
\t 代表 tab (跳格字元)。
\v 代表 vertical tab (即是 ctrl-K)。(在一般文書處理器, line feed 是分行及分段, vertical tab 是分行, 但不分段。)
\w 代表字母、數目字及 underscore, 即是 a-z、A-Z、0-9及 _ , 但不包括標點符號及其他特別字符, 例如不包括 ! @ # 等等。
\W 代表非 \w 的字元, 即是不包括 a-z、A-Z、0-9及 _ 的字元, 例如 /\W/ 符合 #123 或 $30 的 # 或 $。
\xhex 這是用 ASCII 碼來表示一個字元, 使用的是十六進位 (hex) 數字, 例如 /\x5b/ 符合 [OK] 中的 [ 。

 

  在 練習-99 有這句: re=/^\s*\x2b\d\d\d\s+\d{4}\s*\d{4}\s*$/ , 請你使用上表的資料, 看這句如何代表該練習中說的電話號碼規則。

 

7. $1...$9 的使用

  在 regular expression 內, 我們可以用 ( ) 來將一項資料記下來, 稍後用 $1 這代號就可叫用, 若有第二項資料又用 ( ) 記下來, 這可以用 $2 來叫用, 預設最多是 $9。

練習-104 $n 的使用

  這例子的網頁有一個文字框, 你要輸入三個字, 這三個字會用 $1、$2、$3 來代表, 稍後有一個alert對話盒顯示 $1、$2、$3 代表的三個字。

1. 請用瀏覽器開啟示範磁碟中的 , 這網頁有以下內容:


fm> Please fill in three colors you like most.
tx size=20>
checkIt( )>

2. 網頁開啟後, 你會見到一個文字框, 請輸入三個英文字, 例如 green white yellow, 按 [OK], 就會有一個 aler t對話盒出現, 內有以下三項:

 

1. 請先看這句: re = /(\w+)\s+(\w+)\s+(\w+)/ , 這處第一個 (\w+) 就是 $1, 找到的字就用 $1 來代表, 第二個 (\w+) 是 $2, 第三個是 $3, 所以在文字框輸入 green white yellow, 這三個代號就會是 $1=green, $2=white, $3=yellow。

2. $n 是一個 property, 屬於 RegExp這個 object, 使用時, 要在前加上 RegExp 這個object 名稱, 即是 RegExp.$1RegExp.$2RegExp.$3 等等。

3. 每個 $n 只可代表一個字, 若用 global search, 例如 re=/(\w+)/g , 輸入 green white yellow 這三個字, re會代表這三個字, 但 $1 只會代表這三個字最後的一個字, 即是 $1=yellow, $2=, $3= 。

 

 


 跑動文字

  跑動文字 (scroller) 是指會移動的文字, 在 Internet上, 常有人在狀態列 (status bar) 顯示跑動的文字, 不過這項功能不是每個觀看者都喜歡, 因為這會佔去原本用來顯示操作狀態的位置, 例如滑鼠指標在一個連結上, 原本狀態列會顯示這連結的位址, 設定跑動文字後, 這項顯示位址的功能就沒有了, 此外, 這項功能也大量增加 CPU 的操作負擔。

  筆者不說狀態列的跑動文字, 而是說在一個文字框內的跑動文字, 兩者原理一樣, 是在文字框 (或狀態列) 中顯示一句文字, 這句文字移放右方, 然後利用 setTimeout( ) 的方法, 每隔少許時間就向左移一格, 這就做出文字跑動的效果 (不過 CPU 也要做很多工作)。請你先看看示範磁碟中的, 留意文字的移動, 若使用 Netscape, 文字可能會等數秒才出現。

  筆者在這處花一節來說跑動文字, 主要是因為這例子可以示範編寫一個較複雜的程式時, 我們可以逐個階段來編寫, 一個階段成功了, 才繼續寫下個階段, 而不是一次就將整個程式寫出來。這例子的功能分為以下階段:

1. 先造出文字框及在框內放下要顯示的文字。
2. 將文字移到文字框右方。
3. 使文字跑到左方。
4. 使整句文字跑出文字框左邊界。
5. 使文字重複在右方出現及跑到左方。

 

1. 造出文字框及顯示的文字

  例如我們要造出一個文字框及顯示 The deadline is on the 30th of this month. Hurry! , 這句文字就是稍後要設定跑動的文字, 請你開啟示範磁碟中的 , 這網頁有以下內容:


fm >
tx size=50>

  這處的 scrtext 是代表要跑動的文字, 這網頁開啟後, 你應見到以下顯示:

 

2. 將文字移到右方

  我們成功造出文字框及顯示的文字後, 就可將文字移去右方, 方法是在文字的左方加上空格, 使用的是以下的 script:


fm> tx size=50>


  這處的 scroller="" 是設定一個名為 scroller 的變數, 初始值是無 (即是 "" )。

  for (i=0; i <= 70; i++) 是使到跟著的 scroller=scroller + " " 執行 70 次, 每執行一次, scroller 就會加一個空格, 最後結果是 scroller 等於 70 個空格。

  scroller=scroller+scrtext 是將 70 個空格加在 scrtext 之前, 所以 scrtext 向右移70 個空格, 這最新的 scroller 等於 " 70 空格 + scrtext "

  這處我們會遇到一個大問題, 在 IE, 文字框內的文字使用比例字寬 (W 與 I 的寬度不同), 而 Netscape 用的是固定字寬 (W 與 I 寬度相同), 所以在 IE, 文字框的空格較窄, 加了 70 個空格會有以下顯示:

  請你用 IE 開啟示範磁碟中的 , 看看是否有上圖的顯示。

  在 Netscape, 空格較寬, 所以 scrtext 這字串會在文字框的右邊界之外, 文字跑動時, 會花一點時間 (數秒) 才在右邊界出現, 所以字串重複出現會有相隔時間, 出現後, 跑動速度會較快。

  假若將這句 scroller=scroller+" " 改為 scroller=scroller+"=", 在 scrtext 前面的不是 70 個空格, 而是 70 個 = 的字符。

 

3. 使文字向左移動

  在上個例子, 筆者在 scrtext 前加了 70 個空格, 若在 0.1 秒後, 在 scrtext 前加 69 個空格, 再在 0.1秒 後, 在 scrtext 前加 68 格, 每 0.1 秒加少一個空格, 文字就會向左移動。在 第10章 說過 setTimeout( ), 在這處我們利用這功能使到一個 function 每 0.1 秒就執行一次。

  請你開啟示範磁碟中的 , 這檔案有以下內容:


fm>
tx size=50>

  這網頁開啟後, 你會見到 scrtext 這句文字一路向左行, 到達最左方後就停下來。

1. 在這網頁, 筆者先設定 pos=71, 這是用 pos 來代表 scrtext 這句文字在左方空格的數目, 所以這一句: for (i=0; i <=pos; i++) , 會使用 scrtext 向右移 71 個空格。

2. 今次使到文字移動的是一個名為 scrolling( ) 的 function, 這 function 在網頁啟動時用 onLoad="scrolling( )" 來啟動。

3. scrolling( ) 這 function 有以下設定:

scroller=""
pos--
for (i=
0; i <=pos; i++)
{
scroller = scroller + " " }
scroller = scroller + scrtext
document.
fm.tx.value = scroller
setTimeout("
scrolling( )", 100)

  這 function 執行前, pos=71, 當這 function 執行第一次, pos-- (即是 pos=pos-1) 將 pos 減 1, 即是變為 70, 因此 for(i=0; i <=pos; i++) 變成 for (i=0; i<=70; i++) , scroller 變成等於 70 個空格, 所以 scrtext 左方有 70 個空格。

4. 第一次的 scrolling( ) 執行至尾, 會啟動 setTimeout("scrolling( )", 100) , 因此在 0.1 秒後, scrolling( ) 再執行一次, 今次 pos-- 使到 pos 再減 1, 因以 for(i=0; i<=pos; i++) 變成 for (i=0; i <=69; i++) , scroller 變成等於 69 個空格, 所以 scrtext 左方有 69 個空格。(在這處, 你看到為什麼筆者說跑動文字會耗用大量 CPU 資源, 因為這 scrolling( ) 是不停的執行。)

5. setTimeout("scrolling( )", 100) 每執行一次, scrtext 左方的空格就少一個, 直至pos 減至等於 0, 使到 for(i=0; i <=pos; i++) 變成 for (i=0; i <=0; i++) , scrtext 就停下來。

 

4. 使整句文字跑出文字框左邊界

  在上一段, 當 scrtext 的第一個字母到達文字框的左邊界 (即是 pos 等於 0), 就會停下來, 在這一段, 我們是要使到這文字繼續向左移, 直至全部文字消失。

  請你開啟示範磁碟中的 , 這檔案有以下內容:



fm>
tx size=50>

1. 這網頁有這一句: x=scrtext.length, 這是查看 scrtext 的長度 (scrtext.length), 並用 x 來代表, 今次例子的 x 開始時是 50。

2. 這網頁加了一個 if...else, 這是檢查 pos < 0 (pos 是否少於 0), 若是 FALSE, 就使到文字向左移, 這是前面第 (3) 段說的操作, 若是 TRUE, 即是 scrtext 已到達左邊界, 就會有以下操作:

if (pos < 0) { scroller = scrtext.substring(scrtext.length - x )
x-- }

  這是使用 scrtext.substring( ) 的功能來抽取 scrtext 的文字來變為 scroller 來顯示。

  在這例子, scrtext 有 50 個字母, 即是 scrtext.length 是 50, 開始時, x 等於 50, 所以 scrtext.substring(scrtext.length - x ) 等於 scrtext.substring(0), 這是從 0 位置開始抽取文字, 即是整句文字會變為 scroller 來顯示。

3. 留意這處有 x-- , 即是執行一次後, x 會變為 49, 所以在下一次 scrtext.substring(scrtext.length - x ) 是等於 scrtext.substring(1) , 這是將 scrtext 從第二個字抽出來變為 scroller, 即是:

he deadline is on the 30th of this month. Hurry!

4. 再下一次, x 變為 48, 所以 scroller 會是:

e deadline is on the 30th of this month. Hurry!

5. 每次減一個字, 看上去就如這句文字跑出文字框左邊界, 最後 x 減至 0, 有這結果: scrtext.substring(50), 所以整句文字不見了。

 

5. 使文字重複顯示

  在上段, 文字全部跑出了左邊界後, 若要它再回來, 我們只需要加多一點指示就可以了, 這一節說到這處, 若你一路能了解前面說的程式發展, 應該能夠完成這最後的一部份, 在這處筆者偷偷懶, 請你試試自行寫出來吧, 若有困難, 請看示範磁碟中的 的原始檔案。

  你明白了跑動文字的原理, 就可以自行創作跑動的方式, 例如可以使到文字同時從右方及左方出現, 然後在中央碰頭, 停留一會, 又各自向左右分開, 等等。

 


( 第 12 章完 )

 

阅读(1230) | 评论(0) | 转发(0) |
0

上一篇:JavaScript 定时器

下一篇:JavaScript 数组

给主人留下些什么吧!~~