一般表示式範例:Wiki 剖析器

Flash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本

這個簡單的 Wiki 文字轉換範例說明規則運算式的一些使用方式:

  • 將符合來源 Wiki 模式的文字行,轉換為適當的 HTML 輸出字串。

  • 使用規則運算式,將 URL 模式轉換為 HTML <a> 超連結標籤。

  • 使用規則運算式,將美元字串 (如 "$9.95" ) 轉換為歐元字串 (如 "8.24 €" ")。

若要取得此樣本的應用程式檔案,請參閱 www.adobe.com/go/learn_programmingAS3samples_flash_tw 。您可以在 Samples/WikiEditor 資枓夾中找到 WikiEditor 應用程式檔案。此應用程式是由下列檔案組成:

檔案

說明

WikiEditor.mxml

WikiEditor.fla

主應用程式檔案,在 Flash 中為 FLA,在 Flex 中為 MXML。

com/example/programmingas3/regExpExamples/WikiParser.as

類別,其中所包含的方法可使用規則運算式,將 Wiki 輸入文字模式轉換為對等的 HTML 輸出。

com/example/programmingas3/regExpExamples/URLParser.as

類別,其中所包含的方法可使用規則運算式,將 URL 字串轉換為 HTML <a> 超連結標籤。

com/example/programmingas3/regExpExamples/CurrencyConverter.as

類別,其中所包含的方法可使用規則運算式,將美元字串轉換為歐元字串。

定義 WikiParser 類別

WikiParser 類別所包含的方法,可以將 Wiki 輸入文字轉換為對等的 HTML 輸出。這並不是非常完備的 Wiki 轉換應用程式,但是卻示範出規則運算式在模式比對與字串轉換上,一些不錯的使用方式。

建構函數以及 setWikiData() 方法只會初始化 Wiki 輸入文字的樣本字串,如下所示:

public function WikiParser() 
{ 
    wikiData = setWikiData(); 
}

當使用者按下樣本應用程式的「測試」按鈕時,應用程式就會叫用 WikiParser 物件的 parseWikiString() 方法。這個方法會呼叫其它幾個方法,而這幾個方法則進而組合所產生的 HTML 字串。

public function parseWikiString(wikiString:String):String 
{ 
    var result:String = parseBold(wikiString); 
    result = parseItalic(result); 
    result = linesToParagraphs(result); 
    result = parseBullets(result); 
    return result; 
}

所呼叫的每個方法— parseBold() parseItalic() linesToParagraphs() parseBullets() —都使用字串的 replace() 方法取代由規則運算式所定義的比對模式,以便將輸入 Wiki 文字轉換成 HTML 格式的文字。

轉換粗體和斜體模式

parseBold() 方法會尋找 Wiki 粗體文字模式 (例如 '''foo''' ),並將其轉換為 HTML 的對等模式 (如 <b>foo</b> ),如下所示:

private function parseBold(input:String):String 
{ 
    var pattern:RegExp = /'''(.*?)'''/g; 
    return input.replace(pattern, "<b>$1</b>"); 
}

請注意,規則運算式的 (.?*) 部分會比對兩個定義 ''' 模式之間,任何數目的字元 ( * )。此 ? 數量詞讓比對變成非貪婪,因此對於 '''aaa''' bbb '''ccc''' 這樣的字串而言,第一個相符的字串會是 '''aaa''' ,而非整個字串 (以 ''' 模式開始和結束)。

規則運算式中的括號定義擷取群組,而 replace() 方法則在取代字串中使用 $1 程式碼,以參考這個群組。規則運算式中的 g ( global ) 旗標會確保 replace() 方法取代字串中所有相符項目 (不只是第一個)。

parseItalic() 方法運作方式與 parseBold() 方法類似,只不過它會查找兩個 (而不是三個) 所有格符號 ( '' ) 做為斜體文字分隔符號:

private function parseItalic(input:String):String 
{ 
    var pattern:RegExp = /''(.*?)''/g; 
    return input.replace(pattern, "<i>$1</i>"); 
}

轉換項目符號模式

如下列範例所示, parseBullet() 方法會尋找 Wiki 項目符號行模式 (如 * foo ),並將其轉換為 HTML 對等模式 (如 <li>foo</li> ):

private function parseBullets(input:String):String 
{ 
    var pattern:RegExp = /^\*(.*)/gm; 
    return input.replace(pattern, "<li>$1</li>"); 
}

位於規則運算式開頭的 ^ 符號與行開頭相符。規則運算式中的 m ( multiline ) 旗標會造成規則運算式比對 ^ 行開頭,而不僅是字串開頭。

\* 模式會比對星號字元 (用反斜線來表示常值星號,而非 * 數量詞)。

規則運算式中的括號定義擷取群組,而 replace() 方法則在取代字串中使用 $1 程式碼,以參考這個群組。規則運算式中的 g ( global ) 旗標會確保 replace() 方法取代字串中所有相符項目 (不只是第一個)。

轉換段落 Wiki 模式

linesToParagraphs() 方法會將輸入 Wiki 字串中的每一行,轉換為 HTML <p> 段落標籤。方法中的這幾行會去除輸入 Wiki 字串的空行:

var pattern:RegExp = /^$/gm; 
var result:String = input.replace(pattern, "");

規則運算式的 ^ $ 符號會比對行的開頭和結尾。規則運算式中的 m ( multiline ) 旗標會造成規則運算式比對 ^ 行開頭,而不僅是字串開頭。

replace() 方法會以空字串 ( "" ) 取代所有相符的子字串 (空行)。規則運算式中的 g ( global ) 旗標會確保 replace() 方法取代字串中所有相符項目 (不只是第一個)。

將 URL 轉換為 HTML <a> 標籤

當使用者按下樣本應用程式中的「測試」按鈕時,如果使用者選取 urlToATag 核取方塊,應用程式會呼叫 URLParser.urlToATag() 靜態方法,將 URL 字串從輸入 Wiki 字串轉換為 HTML <a> 標籤。

var protocol:String = "((?:http|ftp)://)"; 
var urlPart:String = "([a-z0-9_-]+\.[a-z0-9_-]+)"; 
var optionalUrlPart:String = "(\.[a-z0-9_-]*)"; 
var urlPattern:RegExp = new RegExp(protocol + urlPart + optionalUrlPart, "ig"); 
var result:String = input.replace(urlPattern, "<a href='$1$2$3'><u>$1$2$3</u></a>");

使用 RegExp() 建構函數,將規則運算式 ( urlPattern ) 從幾個組成部分組合起來。這些組成部分就是定義規則運算式模式部分的各個字串。

規則運算式模式由 protocol 字串定義的第一部分,定義了 URL 通訊協定:也就是 http:// ftp:// 。括號定義了非擷取群組,以 ? 符號來表示。也就是說,括號只是用來定義 | 替代模式的群組,群組並不會符合 replace() 方法替代字串中的後參考代碼 ( $1 $2 $3 )。

規則運算式的其它每個組成部分都各自使用擷取群組 (由模式中的括號表示),這些群組再用於 replace() 方法之取代字串中的後參考代碼 ( $1 $2 $3 )。

模式中由 urlPart 字串定義的部分「至少」比對下列其中一個字元: a-z 0-9 _ - + 數量詞指出至少有一個字元相符。此 \. 表示需要點 ( . ) 字元。而剩餘部分則比對至少下列一個字元的其它字串: a-z 0-9 _ -

模式中由 optionalUrlPart 字串定義的部分「不符合或符合多個」下列項目:點 ( . ) 字元,後面跟著任何數目的英數字元 (包括 _ - )。 * 數量詞指出有零個或多個字元相符。

replace() 方法的呼叫採用規則運算式,並以後參考組合取代 HTML 字串。

urlToATag() 方法接著呼叫 emailToATag() 方法,後者使用類似的技巧,以 HTML <a> 超連結字串取代電子郵件模式。在此樣本檔案中,用來比對 HTTP、FTP 和電子郵件 URL 的規則運算式相當簡單,這是為了方便說明的緣故。若要更正確比對這類 URL,必須要有更加複雜的規則運算式。

將美元字串轉換為歐元字串

當使用者按下樣本應用程式的「測試」按鈕時,如果使用者選取 dollarToEuro 核取方塊,應用程式會呼叫 CurrencyConverter.usdToEuro() 靜態方法,將美元字串 (如 "$9.95" ) 轉換為歐元字串 (如 "8.24 €" ),如下所示:

var usdPrice:RegExp = /\$([\d,]+.\d+)+/g; 
return input.replace(usdPrice, usdStrToEuroStr); 

第一行定義了比對美元字串的簡單模式。請注意, $ 字元前面有反斜線 ( \ ) 跳脫字元。

replace() 方法將規則運算式當做模式比對項使用,它呼叫 usdStrToEuroStr() 函數來決定取代字串 (以歐元為單位的值)。

當您使用函數名稱做為 replace() 方法的第二參數時,下列項目會被當成參數傳遞至所呼叫的函數:

  • 字串的符合部分。

  • 任可擷取的括號群組相符項目。以這種方式傳遞的引數數目,會隨著所擷取括號群組相符項目的數量而改變。您可以檢查函數程式碼內的 arguments.length - 3 ,判斷所擷取括號群組相符項目的數量。

  • 相符項目在字串中開始的索引位置。

  • 完整的字串。

usdStrToEuroStr() 方法會將美元字串模式轉換為歐元字串,如下所示:

private function usdToEuro(...args):String 
{ 
    var usd:String = args[1]; 
    usd = usd.replace(",", ""); 
    var exchangeRate:Number = 0.828017; 
    var euro:Number = Number(usd) * exchangeRate; 
    trace(usd, Number(usd), euro); 
    const euroSymbol:String = String.fromCharCode(8364); // € 
    return euro.toFixed(2) + " " + euroSymbol;  
}

請注意, args[1] 代表與 usdPrice 規則運算式相符的已擷取括號群組。這是美元字串的數值部分,也就是只有金額數字,而沒有 $ 符號。此方法可用於匯率轉換,並會傳回所得到的字串 (後面會有結尾的 € 符號,而非開頭有 $ 符號)。