2014年8月5日 星期二

為什麼我要開發 Regular Expression Generator - RegexGen.js

RegexGen.js is a JavaScript Regular Expression Generator that helps to construct complex regular expressions.

如同我在 Regular Expression 學習筆記 所說明的:「學習 regular expression 的關鍵,不在於記憶簡寫符號,而是對引擎匹配原理的掌握。」最佳的 regular expression 學習方法,就是先學習正則引擎的匹配原理。想要快速查閱重點的話,可以參考前三篇學習筆記: (1), (2), (3),如果有充足的時間的話,當然還是建議詳閱 Mastering Regular Expressions 這本書。

然而,畢竟正則表達式的語法相當緊湊,想要一眼看懂複雜的表達式,幾乎是不可能的。首先必須熟悉正則表達式的 meta-character (元字元),然後一步一步拆解。雖然有 RegexBuddy 這樣的軟體可以幫忙拆解,但即使能正確的拆解,也可能無法了解作者 (通常是自己) 原本的思考邏輯,或者要避免的問題。

Regular Expression (JavaScript) 學習筆記 (3) - Informal BNF 語法

Informal BNF of Regular Expression of JavaScript (語法篇)

能夠找得到的 regular expression 的 BNF 語法不太多,以下是自己整理的 JavaScript 的 regular expression 的非正式語法,是依照自己的理解與體會所整理出來的,一定有許多錯誤、遺漏以及命名不當的地方,但還是把它列出來,幫助自己快速複習目前已掌握的 regular expression 的完整語法。讀者如果發現有任何錯誤或是有更好的表示方式,請不吝多多指教。

Regular Expression (JavaScript) 學習筆記 (2) - 原理篇 (下)

前言

上一篇介紹了正則引擎的基本功能與原理,接下來介紹功能更為強大的 lookaround (環視)。

Lookaround (環視) 不會佔用匹配字元

有時候,要匹配的文本主體,需要滿足的條件不只一個;或者,需要對上下文進行多重約束。

然而,對於一般的表達式而言,一旦文本匹配成功,便會由表達式所佔有;也就是說,同一段文本,絕不可能同時由兩個表達式所匹配。

另一方面,有時候,需要確保匹配的文本主體不含特定的內容,但是這個特定的內容,不是一個單一字元。在單一字元的情況下,我們可以使用否定型字元組來處理。但是在多重字元的情況下,卻很難使用一般的表達式辦到。

在這樣的需求下,許多新的 flavor (流派) 開始支援 lookaround (環視) 的功能。

對於環視表達式,最重要的特性就是,它們不會 consume (吃掉) 任何字元:不論匹配結果是否成功、不論是肯定型還是否定型、不論是順序還是逆序,引擎都會回到開始匹配前的原點,並且丟棄所有匹配的內容以及過程中儲存的備選狀態。在此之後,引擎才會根據環視表達式的匹配成功與否,進行下一個動作:當匹配成功時,引擎由目前位置繼續下一個表達式的匹配;當匹配失敗時,引擎回溯 (請參考前面回溯的說明) 到上一個儲存點 (這是由上一個表達式所儲存),繼續由上一個表達式儲存的下一個選擇進行嘗試 (或繼續回溯到上上個表達式)。

(環視使用的是一種擴展的 NFA:NFA-λ (也叫做 NFA-ε 或有 ε 移動的 NFA),它允許轉換到新狀態的變換不消耗任何輸入符號。)

可以這樣想像,lookaround (環視) 就像是站在原地不動,向前或向後觀望。依照環視檢視文本的方向,可以區分為 lookahead (順序環視) 和 lookbehind (逆序環視)。

Regular Expression (JavaScript) 學習筆記 (1) - 原理篇 (上)

前言

過去初學 regular expression 時,看了許多入門教學及參考資料,但多數資料幾乎都只是將一些表達式符號一一列出,然後再舉一些無關緊要的範例,以為這樣就可以弄懂 regular expression 了。做為初學者,看到這麼多的表達式符號,就以為 regular expression 很難學。直到看了 Mastering Regular Expressions 這本書,才知道其實是被誤導了。雖然 regular expression 提供了許多簡寫符號,但是大多數的簡寫符號多半只是為了縮短表達式的長度,這些簡寫符號只要在使用的時候查一下,實際使用過就可以熟悉了,根本不需要特別花時間記憶。其實學習 regular expression 的關鍵,不在於記憶簡寫符號,而是對引擎匹配原理的掌握。

正則表達式

正則表達式是強大、極富彈性、高效的文本處理工具。

其通用的模式表示法,具有如同迷你程式語言般的功能,賦予使用者描述和解析文本的能力。 配合上特定工具提供的支援,正則表達式能夠添加、移除、分離 (isolate)、疊加 (fold)、插入 (spindle) 和截斷 (mutilate) 各類型的文本和數據。

完整的正則表達式是由兩類不同的字元構成,特殊字元是由 *, +, ?, ^ 之類的字元構成,稱為 metacharacters (元字元),其餘的字元稱為 literal (文本字元) 或是 normal text characters (普通文字字元)。 可以把 metacharacters 想像為程式語言中的 operator (運算子),而 literal 則是 operand (運算元)。 (事實上,literal 本身也應該算是 operator: literal 中的每個字元,都代表必須匹配一個字元,而且是逐字元匹配。)

完整的正則表達式是由如上述的小的建構模塊單元組成。每個單獨的建構模塊都很簡單,過它們能夠以無窮多種方式組合,要將它們結合起來實現特殊目標,則必須依靠經驗。