簡易正規表示式匹配器

2021-09-29 13:48:54 字數 3419 閱讀 5088

最近在讀《**之美》,這邊把閱讀過程中的感悟記錄下來。第一章實現了乙個簡易的正規表示式匹配器,用來處理以下的模型。字元 含義c 匹配任意的字母 c.(句點) 匹配任意的單個字元^ 匹配輸入字串的開頭$ 匹配輸入字串的結尾* 匹配前乙個字元的零個或者多個出現原文用 c 語言實現了乙個最小的正規表示式**塊,它可以很好地詮釋正規表示式的基本思想,並且能夠識別出一組有用的並且重要的模式,而且它的**長度很短。rob 給出的實現本身就是漂亮**的乙個極佳示例:緊湊、優雅、高效並且實用。這是我所見過的最佳的遞迴示例之一,在這段**中還展示了 c 指標的強大功能。雖然當時我們最關心的是如何通過使程式更易於使用(同時也更易於編寫)來體現良好記法的重要性,但正規表示式**同樣也是說明演算法、資料結構、測試、效能增強以及其他重要主題的最好方式。以下是匹配演算法的**:/* match:在text中查詢regexp */

int match(char *regexp, char text)

while (*text++ != 『\0』);

return 0;

}/* matchhere:在text的開頭查詢regexp */

int matchhere(char *regexp, char text)

/* matchstar:在text的開頭查詢c*regexp */

int matchstar(int c, char *regexp, char text)

while (*text != 『\0』 && (*text++ == c || c == 『.』));

return 0;

}下面是我用 python 重構的:def match(regexp, text):

if not regexp:

return true

if regexp[0] == 『^』:

return matchhere(regexp[1:], text)

for i in range(len(text)):

if matchhere(regexp, text[i:]):

return true

return false

def matchhere(regexp, text):

if not regexp:

return true

if len(regexp) > 1 and regexp[1] == 『*』:

return matchstar(regexp[0], regexp[2:], text)

if len(regexp) == 1 and regexp[0] == 『$』:

return true if not text else false

if text and (regexp[0] == text[0] or regexp[0] == 『.』):

return matchhere(regexp[1:], text[1:])

return false

def matchstar(c, regexp, text):

for i in range(len(text)):

if matchhere(regexp, text[i:]) and matchhere(ci, text[:i]):

return true

return false

討論函式match(regexp, text)用來判斷文字中是否出現正規表示式,如果找到了乙個匹配的例項則返回 true,否則返回 false。如果有多個匹配的例項,那麼函式將找到文字中最左邊的並且最短的匹配例項。match函式中的基本操作簡單明瞭。如果正規表示式給了空字串,那麼始終返回 true;如果正規表示式中第乙個字元是,那麼匹配例項就一定要出現在字串的開頭。如果第乙個字元不是,那麼正規表示式就可以在字串中的任意位置上進行匹配。大部分的匹配工作都是在matchhere(regexp, text)函式中完成的,這個函式將判斷正規表示式與文字的開頭部分是否匹配。函式matchhere把正規表示式的第乙個字元與文字的第乙個字元進行匹配。如果匹配失敗,那麼在這個文字位置上就不存在匹配,因此將返回 false。然而,如果匹配成功了,函式將遞進到正規表示式的下乙個字元和文字的下乙個字元繼續進行匹配。這是通過遞迴地呼叫matchhere函式來實現的。由於可能存在著一些特殊的情況,以及需要設定終止遞迴的條件,因此實際的處理過程要更為複雜些。最簡單的情況就是,當正規表示式遞進到末尾時(not regexp),所有之前的判斷都成功了,那麼這個正規表示式就與文字匹配。如果正規表示式是乙個字元後面跟著乙個,那麼將會呼叫matchstar來判斷閉包是否匹配。函式matchstar(c, regexp, text)將嘗試遞進地在text中匹配後面的部分,如果發現可以使用matchhere匹配成功,並且此時text除去匹配成功的部分,其餘都是字元c時,函式返回 true。如果在正規表示式的末尾包含了乙個,那麼

僅當te

xt位於

末尾時才

會匹配成

功:if

len(

rege

xp)=

=1an

dreg

exp[

0]==

′,那麼僅當text位於末尾時才會匹配成功:if len(regexp) == 1 and regexp[0] == '

,那麼僅當t

ext位

於末尾時

才會匹配

成功:i

flen

(reg

exp)

==1a

ndre

gexp

[0]=

=′』:return true if not text else false

如果沒有包含$,並且當前不是處於text字串的末尾(if text),並且text字串的第乙個字元與正規表示式的第乙個字元相匹配(regexp[0] == text[0] or regexp[0] == 『.』),那麼到現在為止都是沒有問題的,我們將接著判斷正規表示式的下乙個字元是否匹配text的下乙個字元,這是通過遞迴呼叫matchhere函式來實現的。這個遞迴呼叫不僅是本演算法的核心,也是這段**如此緊湊和整潔的原因。如果所有這些匹配嘗試都失敗了,那麼正規表示式和text在這個位置上就不存在匹配,因此函式matchhere將返回 0。其他的方法上述**實現的是最短匹配,考慮這個正規表示式(.),它將匹配任意長度的text,假設給定的text如下:123abc,那麼matchstar(』.』, 『』, 『123abc』)在執行到text中的第乙個字元時就已經結束了,為了實現最長匹配,我們必須對matchstar函式進行改造,使其在匹配成功後也能繼續遞進一直進行到不能匹配為止:def matchstar(c, regexp, text):

flag = false

for i in range(len(text)):

if matchhere(regexp, text[i:]) and matchhere(c*i, text[:i]):

flag = true

else:

if flag:

break

return flag

正規表示式 匹配

字串 void abtr quint32 ab 表示乙個正規表示式 template class bidirectionaliterator class allocator std allocator sub match bidirectionaliterator class match resul...

正規表示式匹配

請實現乙個函式用來匹配包括 和 的正規表示式。模式中的字元 表示任意乙個字元,而 表示它前面的字元可以出現任意次 包含0次 在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串 aaa 與模式 a.a 和 ab ac a 匹配,但是與 aa.a 和 ab a 均不匹配 解法 首先要想到用遞迴處理...

正規表示式匹配

請實現乙個函式用來匹配包括 和 的正規表示式。模式中的字元 表示任意乙個字元,而 表示它前面的字元可以出現任意次 包含0次 在本題中,匹配是指字串的所有字元匹配整個模式。例如,字串 aaa 與模式 a.a 和 ab ac a 匹配,但是與 aa.a 和 ab a 均不匹配 class solutio...