當前位置:
首頁 > 最新 > 刨根究底正則表達式之一:正則表達式概述

刨根究底正則表達式之一:正則表達式概述

一、緣起

計算機世界中有一些非常基礎、重要、應用廣泛而又特別容易讓人困惑的主題,這包括字元編碼、位元組序(即大小端表示)、正則表達式以及浮點數實現、日期時間處理等等。其中,位元組序、正則表達式跟字元編碼的關係非常密切。字元編碼以及位元組序的問題我已經在另一個系列文章《刨根究底字元編碼》中介紹過了,這個系列來討論正則表達式。

不同於字元編碼竟然連一本專著都沒有的尷尬,正則表達式目前市面上並不缺乏專業著作,比如那本被譽為正則表達式學習聖經的《精通正則表達式》就很值得一讀,另外該書的譯者余晟先生所寫的《正則指引》也不錯;如果僅用於入門,則《正則表達式必知必會》肯定不能錯過,還有網上流傳極廣的《正則表達式30分鐘入門教程》也是不錯的入門資料。

但是,結合我自身痛苦的正則表達式學習經歷和運用體會,僅有這些是遠遠不夠的。記得被大家稱之為「輪子哥」的大神級程序員vczh在知乎上說過,當初被正則表達式虐得一氣之下,乾脆自己寫了一個正則引擎(源碼託管在Github上),才算真正徹底搞懂正則表達式(於是被戲稱為「一言不合」就造輪子)。當然不是每個程序員都能如此生猛,但即便都有這麼生猛,似乎也沒必要都像「輪子哥」這樣自己再造一個「輪子」。

那到底應該怎樣才能最高性價比地掌握正則表達式這個神器呢?這正是我寫這個系列文章的目的。

正則表達式是典型的那種沒用過的話,不覺得對自己有什麼影響,可是一旦用過了,就再也回不去了的神器。當然,我這裡所說的「用過」,不是指簡單用用一些基本功能,而是指能夠熟練運用其基本功能和高級功能。用得越熟練,就會越驚嘆於其強大與神奇。

看到這裡,我相信某些學過正則表達式、會使用一些基本功能的童鞋,心裡或許在犯嘀咕了:神器是神器,可這玩意兒看起來就像天書一樣,也太難學、太難懂了,要達到熟練運用的程度,談何容易!短短的一個正則表達式,或許不到10個字元,其中的每個字元都認識,但連在一起,卻越看越迷惑,越想越迷糊……

是的,正則表達式既然被捧上了神器級別的高度,自然是有著相當強大的功能,這當然就意味著其有非常深厚的內涵,也就意味著有很多需要注意的細節。

注意,我這裡沒有說正則表達式是由於複雜而難以理解,這是因為,深厚的內涵不等於複雜,細節很多不意味著難以理解。看到這裡,或許有人有意見了,正則表達式還不算複雜?還不夠難理解?你秀智商呢,還是秀優越感呢?哦,相信我,其實這兩者我都不太沾邊。智商我也只是中等而已,否則早就不在這裡碼字了;而優越感則更提不上——既不高也不富更不帥,何來優越感?!

其實,我真正想說的是,繁複或許是真的,雜亂倒未必。因此,簡單地說正則表達式複雜,似乎不夠準確而客觀。正如跟一個牛叉而又性格獨特(廢話,真正牛叉的人基本上都有獨特的性格)的人打交道,關鍵不在於糾結其性格的獨特、脾氣的古怪,而是重在充分了解並理解其獨特的性格、古怪的脾氣,然後在此基礎上與他/她進行良好的溝通,以便能好好發揮其牛叉之處。

學習並熟練掌握正則表達式的過程也是如此——關鍵在於先要摸透其「性格」到底獨特在哪裡,其「脾氣」又究竟古怪在何方。一旦摸清楚了其「性格」,其「脾氣」,學習起來就事半功倍了。

因此,我下面準備從我自己的角度,先嘗試著來分析一下正則表達式那獨特的「性格」與古怪的「脾氣」,看看究竟為什麼正則表達式給那麼多人的感覺都是那麼難以「親近」。

二、正則表達式為什麼難學?

對於正則表達式的分析和解讀,目前大多數文章和書籍多集中在正則表達式自身,比如對正則表達式的各個元字元、元轉義序列以及匹配原理的分析和解讀上。

當然,這些自然也是很有必要的,而且是學習的主要內容,是理解正則表達式所必需的。然而,很多人在看了大量這類文章和書籍之後,仍然覺得正則表達式很難看懂,不好理解,經常有一種智商被碾壓的即視感。

難道真的是正則表達式的學習者智商不夠嗎?其實,理解一個事物,都應該有兩個維度,或者說兩個層面:

一是,深入到該事物本身裡面去理解;

二是,跳出到該事物外面,站在更高的一個維度或層面來理解。

正如蘇軾那首著名的哲理詩《題西林壁》所說的,「不識廬山真面目,只緣身在此山中」。很多時候往往是這樣,當你只從該事物本身來看的話,就如在雲里霧裡,是遠遠不夠的;而一旦跳出到該事物之外,站在更高的一個角度來看,則又正如王安石的《登飛來峰》中所說:「不畏浮雲遮望眼,只緣身在最高層」。

對正則表達式而言,前者正是目前大多數文章和書籍在做的;而後者,卻很少有文章和書籍能夠跳出正則表達式,站在更高的維度或層面來分析和解讀正則表達式。這裡就包括了《精通正則表達式》和《正則指引》兩書。

這裡需要特彆強調一下的是,我絕沒有貶低上述這兩本專著及其作者和/或譯者之意,而且恰恰相反,這兩本專著正是本系列文章的重要參考書。尤其無論是作為《精通正則表達式》的譯者,還是作為《正則指引》的著者,余晟先生都絕對稱得上是專業而又嚴謹的。

那麼,前面所謂「更高的維度或層面」,到底指的是什麼呢?那就是,從編程語言發展史以及編程範式的角度來看正則表達式。什麼?正則表達式竟然也算得上是一門正式的編程語言嗎?別急,請繼續往下看。

正則表達式有一個非常明顯的特點:高度簡潔、高度抽象。正則表達式中短短的幾個字元,或許就代表了一段複雜的處理邏輯和匹配演算法。

我們知道,程序代碼是對現實事務處理邏輯的抽象,而正則表達式則是對複雜的字元匹配程序代碼的進一步抽象;也就是說,高度簡潔的正則表達式,可以認為其背後所對應的是字元匹配程序代碼,而字元匹配程序代碼,背後對應的是字元匹配處理邏輯。

因此可以這麼認為,字元匹配處理邏輯,抽象為字元匹配程序代碼;字元匹配程序代碼,再進一步抽象為高度簡潔的正則表達式。

所以說,高度簡潔的正則表達式也是高度抽象的

事實上,從編程語言發展的角度來看,正則表達式也是一種編程語言,而且是屬於第4代語言(4GL)——面向問題語言(第1代語言為機器語言——由0和1組成的位串,第2代語言為彙編語言——用接近於英語單詞的助記碼mnemonic code來代替由0和1組成的位串,第3代語言為高級語言——用接近於自然語言的語法元素編寫程序,如C/C++、Java、C#、Perl、Python、PHP、JavaScript等語言,第4代語言為面向問題語言——用針對問題領域專門設計的語法元素編寫程序或表達式,如SQL、SAS、SPSS、LaTeX、Regex(即正則表達式)等,第5代語言為人工智慧語言——Prolog、Mercury、OPS5等;不過,從第4代語言到第5代語言的演化還不是很清晰,目前學術界爭議較大,這裡不作討論)。

第4代語言相對於第3代語言,更專註於其所應用或者說其所適用的某個特定的業務邏輯和問題領域。程序員主要負責分析問題,以及使用第4代語言來描述問題,而無需花費大量時間去考慮具體的處理邏輯和演算法實現(事實上,最初之所以提出第4代語言的概念,就是希望非專業程序員也能做應用開發)。

從編程範式(programming paradigm)的角度上來講,第4代語言屬於聲明式編程範式(Declarative programming paradigm),聲明式編程重在目標而非過程、重在描述而非實現,以聲明式語句直接描述問題,專註於問題的分析和表達,而非專註於處理邏輯和演算法實現過程,其具體的處理邏輯和演算法實現是由語言解析引擎(編譯器或解釋器)來負責的。

當然,這樣一來,這些由語言解析引擎實現的處理邏輯和具體演算法其通用性就會較差,只能適用於某些特定業務或特定領域。也正是這個原因,第4代語言基本都是局限於某些特定領域的,多被認為是領域特定語言DSL(Domain Specific Language)。

區別於演算法實現可由程序員自由靈活設計的通用編程語言GPPL(General-Purpose Programming Language,作為第3代語言的高級語言基本上都屬於通用編程語言),領域特定語言DSL的演算法基本上由語言解析引擎自動實現,程序員靈活設計、自由發揮的空間很小,因此DSL幾乎沒有通用性(而且DSL大都是非圖靈完備的語言),只能專用於解決特定業務方向和業務領域的問題。

比如,SQL是專用於資料庫操作的語言、SAS和SPSS是專用於統計分析的語言、LaTeX是專用於排版的語言,而正則表達式Regex(regular expression)則是專用於處理字元匹配的語言。

理解了這一點,就比較容易理解正則表達式是字元匹配處理邏輯的抽象;更進一步地來說,正則表達式中的某些元字元與特殊結構,可理解為某種具體的程序邏輯和演算法的體現。

比如,正則表達式中的量詞*這一元字元,就是高級語言的處理邏輯「循環結構」的體現(具體來說量詞*代表的是不定次數循環),而前後多個量詞的嵌套就是多層循環的嵌套;或運算符|這一元字元,就是高級語言的處理邏輯「選擇結構」的體現。

而當或運算符|出現在由量詞*所限定的圓括弧中時,其實就是在「循環結構」中嵌套了「選擇結構」;而如果進一步地,「循環結構」所嵌套的「選擇結構」中的某個分支,又被某個量詞*所限定,那麼則相當於「循環結構」所嵌套的「選擇結構」又嵌套了「循環結構」。

理解這一點非常重要,是快速、深入理解正則表達式的一把鑰匙、一條捷徑。站在編程語言發展史和編程範式的高度,再結合對正則表達式本身原理的深入理解,里外結合,高下相較,既登高望遠、一覽眾山小,又洞幽燭微、復觀千水深,正則表達式的奧義,就能盡在掌握之中了。

當然,正則表達式之所以難學、難理解,除了由於正則表達式作為一個字元匹配領域的領域特定語言(DSL),具有高度簡潔、高度抽象的特點之外,大致上應該還有以下幾個原因:

1) 學習者不求甚解,不了解正則引擎內部的基本原理

作為正則表達式的使用者,不需要深入了解正則引擎內部原理的技術實現細節,那是正則引擎開發者更應該了解的;但若完全不了解其基本工作原理和運行機制,也是不足取的。

2) 有多個多義元字元,特別容易使人混淆、迷亂

比如-、+、?、^,尤其是元字元?,既可以作為量詞表示其所限定的子表達式為可選(即匹配0次或1次),也可以置於量詞之後表示懶惰匹配,而且還有很多特殊分組結構中用到它,比如(?sub-regex)、(?:sub-regex)、(?>sub-regex)、(?=sub-regex)、(?!sub-regex)、(?

3) 轉義也是難點

什麼情況下需要轉義,什麼情況下不需要轉義,貌似複雜得令人抓狂;當然,其實是有一定的規律的,掌握了這些規律,再遇到轉義問題,就不至於心潮澎湃了。

4) 學習期望與學習方法不對

不應該期望一次性記住、學會並熟練運用,正確的學習姿勢應該是:先簡單入門,對一些基本的規則與元字元大致了解一遍,有個印象就好,在需要時再回過頭來看,不用刻意去強行記憶;然後接下來就應該多練、多實踐、多運用,邊學、邊深入、邊熟練。

5) 有用於入門的好教程、備忘單,也有用於深入的大部頭專著,但卻缺乏好的速查手冊

由於需要邊學、邊深入、邊熟練,因此,平時手頭邊更需要的不是簡單的入門教程、備忘單(Cheat Sheet),也不僅僅是知識點分散於各處的大部頭專著(知識點分散導致查找起來不方便,用於深入學習原理是不錯,但不夠實用),而是一本按語法元素將知識點綜合在一起進行編排的、在需要回過頭來看時能夠隨時快速翻查的速查手冊。這樣,在實踐運用中遇到問題就可方便隨時快速翻查,而這一點恰恰對於正則表達式這種不可能短期內快速掌握並熟練運用的專業工具的學習與使用非常重要。

6) 沒有使用好的學習工具

你知道regex101.com、RegexBuddy、regexper.com等正則表達式的專業網站和專業工具嗎?這些堪稱學習正則表達式的神器,可令學習事半功倍,但很多人不知道,或知道但很少使用。

正則表達式可視化工具(regexper.com)

三、正則表達式概念

一)先從「通配符」說起

對於初學者而言,正則表達式,僅從字面上來說不太好理解。但實際上,您可能早已經使用過了某些正則表達式的功能,只是自己還沒有意識到而已。

因此,所謂「通配符」,即「通用匹配字元」,就是用某個通用字元按事先所規定的規則來查找匹配某些常規字元,從而實現「以一對多」(或「以一代多」)、「以簡對繁」(或「以簡代繁」)地簡化、抽象化、通用化用來進行查找匹配的表達式的目的。

然而,儘管使用「通配符」的匹配查找方法很有用,但它的功能還是非常有限的。和通配符類似,正則表達式也是用來進行文本匹配查找的工具。只不過相比通配符而言,正則表達式更為抽象化、通用化,功能也更為強大、更加靈活,能夠更為精確地表達匹配條件(即匹配規則),當然也就更複雜,更難以學習和掌握。

二)正則表達式概念

正則表達式,又稱正規表示法、常規表示法(Regular Expression,在代碼中常簡寫為regex、regexp或RE),計算機科學的一個概念。

正則表達式是一種字元串的匹配模式,描述的是某一類字元串的共同特徵。

所謂模式,就是模板樣式或模具樣式。正如符合某種樣式的模板或模具,可以用來生產符合這種樣式的同一類產品一樣;反過來,也可以用某種樣式的模板或模具,來檢驗或框定哪些產品才是符合這種樣式的同一類產品。

正則表達式正是類似於這樣的模板或模具,用來檢驗或框定哪些字元串是符合正則表達式所描述的字元串共同特徵的同一類字元串;而這個檢驗或框定的過程,就稱之為匹配。

我們平時所使用的自然語言中,可以用「漂亮」、「堅固」、「挺拔」等高度抽象性詞語來描述事物的共同特徵一樣,一個正則表達式正是某一類字元串的高度抽象,用來描述這類字元串的共同特徵。也就是說,一個正則表達式代表了某類字元串的一個集合,而正則表達式相當於對該字元串集合的特徵性質描述。(註:集合的常用表示方法有元素列舉法、特徵性質描述法和圖示法。)

正則表達式還可看作是對字元串操作的一種邏輯公式,其構造方法和創建數學表達式的方法差不多,也就是用普通字元(如字母a到z、數字0到9等)和事先定義好的一些特定字元(專業術語稱之為元字元),以及這些字元的組合,組成一個特定的規則字元串。而所謂特定的規則,即是正則;因此特定的規則字元串,即是正則表達式。

這些「特定的規則」,從被匹配的字元串的角度上來看,可以認為描述的是某一類字元串的共同特徵;而從正則表達式的角度上來看,也可以認為表達的是一種匹配規則(或稱過濾邏輯)。

因此,正則表達式是一種特殊的字元串(即正則表達式字元串,往往直接簡稱為正則表達式或正則式),用來描述、匹配、過濾符合某些特徵的其它字元串(即輸入字元串、源字元串、被測試的字元串、被匹配的字元串,往往直接簡稱為字元串)。

說某個正則表達式匹配某個字元串,通常是指這個字元串的全部或一部分或幾部分分別符合或者說滿足正則表達式所描述的字元串特徵;也可以說是指這個字元串的全部或一部分或幾部分分別符合或者說滿足正則表達式所規定的匹配條件或匹配規則。

而從正則表達式作為一種編程語言的角度上來看,正則表達式的基本語法結構與一般高級編程語言差不多,主要就是順序(即連接)、選擇(即分支)、循環(即重複)三種,其他都是這三者的組合,再加上一些語法糖。

再更進一步地,從正則表達式作為一個聲明式編程範式的領域特定語言DSL的角度來講,正則表達式的順序、選擇、循環這三種基本語法結構是非常簡潔、緊湊的(這幾乎是聲明範式DSL的基本特點,而正則表達式將這一點體現得尤為淋漓盡致)。其中,連接無需通過元字元表示,選擇通過元字元「|」表示,而循環則通過元字元「*」、「+」或「」表示。這三種基本語法結構在使用時,直接進行聲明式描述即可,無需通過複雜的語句來進行演算法設計。

事實上,還可從編程語言操作符(即運算符)的角度來理解,其中,「*」、「+」或「」是單目後綴操作符,「|」是雙目中綴操作符,連接其實也是雙目中綴操作符,不過是隱含的(即隱式的,因為連接是三種基本語法結構中最常用的,所以設計為隱式操作符最為合理)。

四、正則表達式功能

一般而言,典型的簡單搜索和替換操作,可通過直接提供與預期的搜索結果相匹配的字面文本來實現。雖然這種方法對於文本執行簡單的、靜態的搜索和替換任務可能已經足夠了,然而卻缺乏足夠的靈活性和動態性。

若通過使用正則表達式,則可以:

查找文本

提取文本

驗證文本

替換文本

切分文本

顯然,通過使用文本模式,正則表達式相比較於直接使用固定的、明確的字面文本進行簡單的、靜態的搜索和替換,更為靈活,也更具有動態適應性。而且,正則表達式同樣也可以使用字面文本進行簡單的、靜態的搜索和替換(當然,這有點大材小用了,效率也比直接搜索和替換更低,因此,字面文本的直接搜索和替換,不推薦使用正則表達式)。

因此,正則表達式的熟練運用,是文本處理人員,尤其是編程人員的必備技能。其強大的功能、快捷的速度,一旦掌握,你將會既嘆服於心,又享受其中。

五、正則表達式簡史

正則表達式的「祖先」可以一直追溯至對人類神經系統如何工作的早期研究。Warren McCulloch和Walter Pitts這兩位神經生理學家在20世紀40年代研究出用一種數學方式來描述神經網路。

1956年,一位叫Stephen Kleene的數學家在McCulloch和Pitts早期工作的基礎上,發表了一篇標題為《神經網路事件表示法和有窮自動機(Representation of events in nerve nets and finite automata)》的論文,引入了正則表達式的概念。正則表達式就是用來描述他稱為「正則集合Regular Sets」的表達式,這就是「正則表達式」這個術語的來源。

隨後,大名鼎鼎的Unix之父——Ken Thompson於1968年發表了文章《正則表達式搜索演算法(Regular Expression Search Algorithm)》,並且將正則表達式這一符號系統引入了他自己開發的編輯器qed以及之後的編輯器ed中,然後又被移植到了大名鼎鼎的文本搜索工具grep中。自此,正則表達式被廣泛應用到各種Unix系統或類Unix系統(如Mac系統、Linux系統)的工具中。

由於正則表達式異常強大而實用的功能,越來越多的語言和工具引入了正則表達式。不過遺憾的是,始終沒有確立正則表達式方面的標準,導致各語言與工具中的正則表達式雖然功能上大體類似,但細微差別仍然不少。於是,誕生於1986年的POSIX開始進行標準化的嘗試。

POSIX,是Portable Operating System Interface for uniX(可移植Unix操作系統介面)的縮寫。POSIX是一系列規範,定義了Unix操作系統應當支持的功能,其中也包括正則表達式的規範。

因此,Unix系統或類Unix系統上的大部分工具,如grep、sed、awk等,均遵循該標準。遵循POSIX正則表達式規範的這些語言和工具中的正則引擎,往往習慣將它們稱之為POSIX流派的正則引擎。

之後,1988年6月,Larry Wall開發的Perl語言發布第2版,其中所引入的正則表達式引擎大放異彩。Perl 2的正則表達式引擎源於Henry Spencer編寫的regex的增強版。之後不斷改進,影響越來越大。於是在此基礎上,1997年又誕生了pcre——Perl兼容正則表達式(Perl Compatible Regular Expressions)。

PCRE是一個由Philip Hazel開發的、為很多現代語言和工具所普遍使用的Perl正則表達式兼容引擎,現已成為除了Unix上的工具所遵循的POSIX標準之外的其他大部分語言和工具所隱然遵循的另一個事實上的標準。因此,往往習慣將這些Perl正則表達式兼容引擎稱之為PCRE流派的正則引擎。

POSIX流派與PCRE流派是目前正則表達式引擎流派中的兩大最主要的流派。

之後,正則表達式在各種計算機語言或各種應用領域進一步得到了更為廣泛而普遍的應用和發展。

六、正則表達式流派

如前所述,目前正則表達式主要有兩大流派(Flavor):POSIX流派與PCRE流派。

1)POSIX(Portable Operating System Interface for uniX)流派

POSIX是一系列規範,定義了UNIX操作系統應當支持的功能,其中也包括正則表達式的規範。POSIX規範的正則表達式流派是PCRE之外的另一大流派。

POSIX規範定義了正則表達式的BRE(Basic Regular Expression基本正則表達式)和ERE(Extended Regular Express擴展正則表達式)兩種標準。早期,BRE與ERE的區別主要在於:

不過,後來隨著BRE與ERE逐漸相互融合,現在的BRE和ERE(包括GNU改進的GNU BRE和GNU ERE)在功能特性上並沒有太大區別,主要的差異是在元字元的轉義上。

在遵循POSIX規範的UNIX/LINUX系統上,vi/vim、grep和sed遵循POSIX規範的BRE標準,egrep、awk則遵循ERE標準。這些UNIX/LINUX系統常用工具的正則表示法與PCRE對比如下:

注1:vim中的?和=都表示匹配0或1個前面的子表達式,但?不能在反向查找的「?」命令中使用。

注2:vim中的右花括弧}之前可以不加反斜杠,也可以加反斜杠,比如:。

注3:PCRE中常用來表示「單詞的起始或結束位置」,但Linux/Unix的工具中,通常用來匹配「單詞的結束位置」,而sed中的y則與PCRE中的一樣,可同時匹配這兩個位置。

2)PCRE(Perl Compatible Regular Expression)流派

目前大部分常用編程語言中常見的正則表達式語法,其實都源於Perl。其中,PCRE就是從Perl衍生出來的最為著名的一個流派,d、w、s之類的字元組簡記法,是這個流派的顯著特徵。

不過,雖然PCRE流派是從Perl語言中衍生出來的,但與Perl語言的正則表達式還是有一些細微差異的,比如PHP的preg(Perl Regular Expression)與Perl的差異可看這裡。

(註:PHP支持兩種不同的正則引擎:ereg與preg,ereg全稱為Extended Regular Expression,屬於POSIX ERE;ereg由於功能方面的不足,已經逐漸被preg替代了,ereg將在未來被廢棄。因此,若非特別說明,後文中當提到PHP正則引擎時,默認指的是PHP preg正則引擎。)

考慮到目前絕大部分常用編程語言所採用的正則引擎基本屬於PCRE流派,因此,本系列文章將以PCRE流派為主、以POSIX流派為輔進行介紹;文中有關各語法元素的解釋,若非特別說明,均以PCRE流派為準。

另外,如前所述,當我們在介紹正則表達式的流派時,與Perl正則規範相兼容(包括直接兼容與間接兼容)的流派習慣用PCRE來稱呼。

而本系列文章在介紹與Perl正則規範直接兼容(但除Perl外並非完全兼容)的語言或正則庫或工具程序,比如Perl、PHP preg、PCRE庫時,一般稱之為Perl系;與之對應的還有間接兼容的Java系(包括Java、Groovy、Scala等)、.Net系(包括C#、VB.Net)、Python系(包括Python2和Python3)、JavaScript系(包括原生JavaScript和擴展庫XRegExp)等等。

也就是說,Perl系、Java系、.Net系、Python系、JavaScript系(另外還有Ruby、C++Builder、Delphi等)均屬於PCRE流派,但與Perl的兼容性(即兼容程度)各有不同。其中,Perl系兼容性最好,雖然PHP preg與PRCE庫並非與Perl完全兼容,但基本兼容,因此屬於直接兼容;而其他語言或工具相對Perl系而言,與Perl的兼容性較差,則屬於間接兼容。

七、本系列文章的體例及後續內容

本系列文章出自於我自己在學習正則表達式的過程中所經歷過的真切體會和真實痛點。因此,正如前面所述,採取的編排風格會類似於速查手冊。不過,與一般的僅供入門使用的字典式簡易手冊不同,這將會是一本更為深入的專業級速查手冊。這也正是文章名稱中特彆強調「刨根究底」,而不是直接名之為速查手冊、快速參考之類的原因。

本系列文章當然會涉及到正則引擎內部的相關匹配原理與匹配機制的解釋(而且還獨創性地總結為了八大原則,便於「以簡馭繁」、「提綱挈領」地快速掌握要領以便於記憶和理解),只是與其他專著用專門章節進行介紹不同,而是各自糅合於對相關語法元素的解釋之中了。

這種為了便於快速翻查而沒有將匹配原理與匹配機制予以專章介紹的特殊編排,自然也有其缺點(比如,你可能會在不同的語法元素中發現類似的雷同解釋,這或許有重複啰嗦之嫌,但畢竟這符合我們的編排目的),但問題在於市面上進行專章介紹的專著已經有很多了,再重複它們意義不大;而專門針對前述的正則表達式學習和運用痛點的文章和專著則基本沒有,而這正是本系列文章的意義和目的所在。

也因此,出於更偏向於實踐運用的目的,本系列文章不會花費過多的筆墨在DFA、NFA等過於深入的正則表達式幕後技術細節的講解上。事實上,我認為只要大致了解它們的基本原理與工作機制以及兩者之間在功能特性上的差異,就完全可以熟練掌握並運用正則表達式了,除非你是想自己開發一個正則引擎,實在沒必要陷入DFA、NFA等的技術實現細節中。

我相信通過反覆閱讀本系列文章,再多加練習、勤於實踐,然後在實際運用時再不斷回過頭來隨時翻看,應該完全可以熟練掌握這個像毒品一樣會讓人上癮的神器。

最後,再說一下本系列文章後續將會涉及到的內容:首先會大致簡單介紹一下正則表達式語法基礎,接下來對元字元、元轉義序列、特殊構造(特殊結構)等正則表達式的語法元素進行逐個詳解;之後,再講解一下匹配模式、POSIX字元組方括弧表達式以及字元組運算;最後是正則表達式各語法元素優先順序介紹。


點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 優才學院 的精彩文章:

技術員工的工作滿意度:數據可以告訴我們什麼?
MYSQL 優化常用方法
六個優雅的 Linux 命令行技巧
CSS 常見布局方式
一篇文章,教你學會Git

TAG:優才學院 |