1. 程式人生 > >正則表示式的實現原理(一)

正則表示式的實現原理(一)

開發十年,就只剩下這套架構體系了! >>>   

正則表示式大家已經非常熟悉,這裡不是教大家怎麼用,而是說明如何用程式碼實現正則表示式。該篇先理清正則表示式的組成結構:

1、正則表示式描述的是一個字串的匹配模式,本質上是一個字串的集合,如果給定的字串屬於該集合就說明該字串與模式相匹配;(比如在談談KMP演算法中提到的判斷某個長文字是否包含指定關鍵字的場景就是分析長文字的子串是否包含在模式描述的集合中,本質上是模式匹配問題,更確切的講應該是單模式匹配,因為以後還要提到多模式匹配問題。這同樣也解釋了為什麼把簡單的字串查詢問題說成一個高大上的模式匹配問題的原因(至少我個人以前是這麼認為的))

2、再次強調以集合的觀點來看待正則表示式,以上提到了集合,那麼“(空)”是屬於任何集合的,也就是說空本身就是一個正則表示式;

3、先認識簡單的正則表示式。任何單個字元都可用正則表示式表示,表示的方式多種多樣:

   (1)簡單的字元常量如:字母、數字、標點符號以及一些空白符(常見的如\t\n\r,不常見的自己查吧)

   (2)字元常量表示的正則表示式是單一的因為集合中只有自身,因此有很多靈活的表示方法如:

           \d、[0-9]表示0-9的數字,[]可以用來表示更個性化的情況如[135]表示只能是1、3、5這3個數字中的一個;

           \D、[^0-9]、[^\d]表示非數字字元;

           \w、[_0-9a-zA-Z]表示所有的大小寫字母、數字與下劃線;

           \W、[^\w]、[^_0-9a-zA-Z]表示除大小寫字母、數字與下劃線的其它字元;

            \s、[ \t\n\r]表示空白字元;

            \S、[^\s]、[^ \t\n\r]表示除 \t\n\r空白符的其它字元;

            .可以表示除\n外的任何字元

    (3)連線運算子是一個隱藏的運算子,將兩個正則表示式按照順序並列寫出即可,表示的是兩個集合的笛卡爾積,比如:ab、a\d、\d\s等等,注意只要是合法的正則表示式就可以連線,這實際上是一個遞迴的思想,在後面的某些運算中一樣適用;

    (4)或運算(|)表示兩個正則表示式所組成集合的並集,如:a|b、\s|\S、a|ab,需注意或運算的優先順序小於連線;

    (5)括號()運算用於改變優先順序如:(a|b)c表示集合{ac,bc},很明顯括號有最高的運算優先順序;

    (6)次數運算子,用於描述正則表示式重複出現的次數,如:a?,a+,a*分別表示a可出現0次或1次,a至少出現1次,a可出現0次或多次。也可精確指出匹配的次數:a{4}表示a只能出現4次,a{4,7}表示可出現4-7次,a{4,}表示至少出現4次;