【转】刨根究底正则表达式(2):文本查找方式的演化历史
上一篇文章講到,從根源上來講,正則表達(dá)式是為了解決文本的查找問題(也稱為匹配問題)而誕生的。不過,文本查找方式的歷史,要遠(yuǎn)早于正則表達(dá)式。
那么,在正則表達(dá)式出現(xiàn)之前,文本查找方式經(jīng)歷了什么演化過程呢?
最后為什么又出現(xiàn)了正則表達(dá)式呢?換言之,正則表達(dá)式的出現(xiàn),在文本查找方面,解決了其出現(xiàn)之前所不能解決的什么問題呢?
接下來我們一起來尋找這些問題的答案。
直接字面查找方式
正則表達(dá)式其中最基本的功能是為了滿足文本查找的需求,而文本查找需求,是一種非常基礎(chǔ)、極為常見的需求。
很自然,最先想到和做到的當(dāng)然就是直接的字面文本查找(簡(jiǎn)稱字面查找)。所謂“字面文本”,指的是用于查找的文本本身就是直接要查找的文本,也就是說,用于查找的文本沒有特殊含義,就表示文本本身字面上的含義。
比如要查找文本“張三”,就直接以文本“張三”去進(jìn)行查找。
但有時(shí)我們的查找需求要更為復(fù)雜一些,比如不僅要查找“張三”,還有“李三”、“王三”等所有名字中含有“三”這個(gè)字的兩字姓名。
這種情況下,姓名中的姓就是不確定的了,那怎么辦呢?于是比直接的字面查找更為強(qiáng)大、更為方便的另一種查找方式出現(xiàn)了:間接的模式查找方式。
間接模式查找方式
這里出現(xiàn)了一個(gè)關(guān)鍵術(shù)語:模式。那什么是模式呢?
我們知道,工廠生產(chǎn)產(chǎn)品,往往需要先有產(chǎn)品的模板或模具。而模式,就是模板樣式或模具樣式。
正如符合某種樣式的模板或模具,可以用來生產(chǎn)符合這種樣式的同一類產(chǎn)品一樣,反過來,也可以用某種樣式的模板或模具,來檢驗(yàn)框定或篩選過濾出哪些產(chǎn)品才是符合這種樣式的同一類產(chǎn)品。
比如,以上面這個(gè)查找案例來說,從“張三”、“李三”、“王三”等所有名字中含有“三”這個(gè)字的兩字姓名中抽取出來的查找模式可能是這樣的:“?三”,其中的“?”代表所有的單姓。
(注:為簡(jiǎn)化討論,我們這里假定用于查找的文本僅限于姓名,不包括非姓名的其他文本,比如不包括“一二三”這樣的文本,而且也暫不考慮兩字姓名以外的其他三字姓名、四字姓名等。)
因此,就可以用“?三”這個(gè)查找模式來篩選過濾出所有兩字姓名中以“三”這個(gè)字為名字的姓名。 換句話說,只要是所有兩字姓名中以“三”這個(gè)字為名字的姓名,都屬于符合“?三”這個(gè)模式的同一類姓名,因此都可以通過該模式查找匹配出來。
這里,用于查找的文本模式“?三”,并不是我們要直接查找的文本本身,“?三”中的“?”并不是表示“?”這個(gè)字符的字面本身——問號(hào)字符,而是具有了特殊含義——表示所有的單姓,因而“?”在這里具有了一定程度的抽象性、代表性、通用性和普適性。
間接模式查找方式目前大致上可劃分為“通配符查找方式”和“正則表達(dá)式查找方式”兩種,下面分別進(jìn)行簡(jiǎn)要介紹。
通配符查找方式
通配符查找方式,在操作系統(tǒng)的文件查找功能中使用得非常普遍。
在這種間接的模式查找方式中,通常使用到的通配符除了上面提到的?號(hào),還有*號(hào)。
在操作系統(tǒng)中,一般使用?和*這兩個(gè)具有抽象性、代表性和通用性的通配符來查找硬盤上的文件。其中,?通配符所規(guī)定的查找規(guī)則是查找文件名中的單個(gè)字符,而*通配符所規(guī)定的查找規(guī)則是查找文件名中的零個(gè)、一個(gè)或多個(gè)字符。
比如像“data?.dat”這樣的查找模式,將可以查找到下列文件名:
data1.dat
datax.dat
dataN.dat
而像“data*.dat”這樣的查找模式,則可以查找到下列文件名:
data.dat
data1.dat
data12.dat
datax.dat
dataXYZ.dat
因此,所謂“通配符”,即“通用的查找匹配字符”,就是將某些字符(比如?號(hào)和*號(hào))規(guī)定為特殊的用于查找文本的通用字符。
用某個(gè)通用字符按事先所規(guī)定的規(guī)則來查找某些常規(guī)字符,從而實(shí)現(xiàn)“以一對(duì)多”(或“以一代多”)、“以簡(jiǎn)對(duì)繁”(或“以簡(jiǎn)代繁”)地進(jìn)行查找。
相比較于直接的字面查找方式只能“以一對(duì)一”、“以多對(duì)多”,或者說“以簡(jiǎn)對(duì)簡(jiǎn)”、“以繁對(duì)繁”,通配符查找模式顯然更加抽象化、模式化,所以也就更為通用化、普適化。
然而,盡管通配符查找方式比直接的字面查找方式更強(qiáng)大、更方便、更通用、更普適,但它的功能還是非常有限的,無法精確而靈活地表達(dá)更為復(fù)雜的查找條件(即查找規(guī)則)。
比如無法分組、沒有分支結(jié)構(gòu)(即不支持“或運(yùn)算”)、不支持量詞(即不支持循環(huán))、不支持字符組等等。
比如,我們不僅要查找兩字姓名中的名為“三”字的所有姓名,還要查找兩字姓名中的名為“四”字的所有姓名,如果使用通配符查找方式的話,怎么辦呢?
由于通配符查找方式?jīng)]有分支結(jié)構(gòu),不支持或運(yùn)算,即不支持類似于“?三|?四”這樣的寫法,則只能分兩次進(jìn)行查找,這顯然非常不方便。
再舉個(gè)例子,如果我們要查找文件系統(tǒng)中命名為DxxxDxxxDxxx.dat的所有文件(其中的x代表任意字符),由于通配符查找方式不支持分組和量詞,也就是不支持類似于“(D?{3}){3}”這樣的寫法,也是相當(dāng)麻煩的。
正則表達(dá)式查找方式
查找需求的多樣化和復(fù)雜性,呼喚著比通配符查找方式更加強(qiáng)大、更加方便、更加通用、更加普適的查找方式。
于是,能夠更為精確、更為靈活地表達(dá)更加復(fù)雜、更加抽象、更加通用、更加普適的查找條件的全新查找方式——正則表達(dá)式就應(yīng)運(yùn)而生了。
因此,站在查找方式的歷史演化角度上來看,通配符查找方式可認(rèn)為是正則表達(dá)式的前身,或者換言之,正則表達(dá)式是通配符查找方式的升級(jí)版。
和通配符類似,正則表達(dá)式也是以間接的模式來進(jìn)行文本查找的。顯然,相比較于前面所述的“直接字面查找”方式來說,通配符查找方式和正則表達(dá)式查找方式這兩種以模式進(jìn)行查找的方式就是“間接模式查找”方式。
比如,還是前文所述的例子,我們不僅要查找兩字姓名中的名為“三”字的所有姓名,還要查找兩字姓名中的名為“四”字的所有姓名,用通配符查找方式是只能分成兩次進(jìn)行,但如果使用正則表達(dá)式查找的話,只需查找一次,并且寫法非常簡(jiǎn)潔:.三|.四,顯然更為方便。
同樣,如果我們要查找文件系統(tǒng)中命名為DxxxDxxxDxxx.dat的所有文件(其中的x代表任意字符),使用通配符查找方式的話,查找表達(dá)式寫起來也是很麻煩的,但如果使用正則表達(dá)式的話,只需寫作:(D.{3}){3},正則表達(dá)式的表達(dá)能力明顯比通配符強(qiáng)得多。
顯然,正則表達(dá)式查找方式相比較于通配符查找方式來說,更為淋漓盡致地體現(xiàn)了“以一對(duì)多”(或“以一代多”)、“以簡(jiǎn)對(duì)繁”(或“以簡(jiǎn)代繁”)的模式查找方式的特點(diǎn)。
這就是正則表達(dá)式?之所以被發(fā)明出來的原因。
不過,既然正則表達(dá)式更為抽象化、通用化和普適化,也更為模式化,功能也更為強(qiáng)大、更加靈活,當(dāng)然也就更為復(fù)雜,更難以學(xué)習(xí)和掌握。
畢竟,強(qiáng)大靈活與簡(jiǎn)單易用,始終都是一對(duì)矛盾。
總結(jié)
以上是生活随笔為你收集整理的【转】刨根究底正则表达式(2):文本查找方式的演化历史的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 降准和降息哪个影响大?对股市利好还是利空
- 下一篇: 没有招商银行可以申请信用卡吗?招行信用卡