終於用boost的正則庫寫完了一個文本轉換

     過程真是艱苦啊,對文本結構分析的不全面,一度讓我以爲BOOST的REGEX庫有缺陷。還好,最終證明是自己的問題,呵呵,否則重新用其他方法實現的話,真要讓人崩潰了。

     但是其中還有一點小問題,類似如下的正則

#define REG_LINE "[ ]*"                                /*標記頭*//
                 "((//w+)|"                                        /*元素名情況1  例如:TYPE*//
                 "(/"([^/"]*?)/"))"                                /*元素名情況2  例如:"wms_title"*//
                 "[ ]+"                                    /*空格*//
                 "((/"([^/"]*?)(?=/"))|"                                /*值情況1  例如: "rw:sdf" 也包含了下面的情況2*//
                 "((-?//w+[ ]*)*?(?=//r//n))|"                    /*值情況3  例如: 129 -35 222*//
                 "(//S+))"                                        /*值情況4  ../mapfile/ */

紅色部分的表達式獲取的是 "sdfsadfsadfdf”  這種形式的內容。但是若引號不想獲取,改成 ((?=/")([^/”]*?)(?=/”)) 這種形式,則正則會產生中斷

若改成 [ ]+(?<=/”)(([^/”]*?(?=/”)) ,則正則不錯出現中斷,但是獲取的內容有誤

最後的解決方法只能是對獲取的 字符串單獨進行處理,用此正則 "((?<=/")([^/"]*?)(?=/"))"進行獲取,若是"sdfsadfsadfdf”的形式,則獲取引號內的內容,若不是這種形式,不處理。

不限次數的嵌套正則寫法:

"(1|2|3|4)((?!1|2|3|4|END)(.*?)|(?R))*END"

1,2,3,4是可以作爲開頭元素的關鍵字,END是結尾標誌,此正則配合迭代器可以獲取所有並列的最外層嵌套,如果在用一個循環,則可以獲取每一個嵌套的內容,相當之方便。

用了正則表達式對文本的處理確實相當方便。但同時也是一把雙刃劍,考慮的情況不周全導致正則表達式設計的不完善,就可以導致許多莫名奇妙的錯誤,很難檢測出來。

我就是吃了這個苦,排錯過程相當鬱悶,一度認爲是BOOST的語法原因,差點都懷疑BOOST的REGEX是否真的如傳說中的那麼強大了。

哎,滿臉都是淚。

 

 

ps:

似乎對於這種表達式:  [ ]*NAME//b[ ]+((//w+)|((?=/")[^/"]*?(?=/")))[ ]*//r//n    紅色部分有問題,不能獲取直接獲取引號中間的內容,只能分2個步驟,先連引號一起獲取,然後在單獨獲取引號內的內容。與上面粉紅色標記的情況一樣

 .

 

 

對於“|”符號的機制,比如   (/S+|/(.*?/)[ ]*?(?=/n))        boost::regex 裏的處理機制是,若第一種(/S+)能匹配,則立刻停止或條件,即使第2種情況(/(.*?/)[ ]*?(?=/n)) 能匹配更長的字符串,比如 (('[ADMINCODE]' eq '330523') or ('[ADMINCODE]' eq '330483')or('[ADMINCODE]' eq '330682'))  ,此正則只能匹配(('[ADMINCODE]'  ,若想匹配整個,則將2種情況互換一下位置即可。即 若正則A和B,A是B的子集,不要寫成B|A, 而是 A|B

 

 

 

以上的一些問題在轉載的《深入淺出正則表達式》裏面介紹機制的時候都提到了一些產生的緣由。比如:"?=","|"

 

 

對於這樣的正則 :"CONFIG[ ]+?(/"[^(/"|//n)]*?/")[ ]*?/"([^(/"|//n)]*?)/"[ ]*?//r//n"

 

其中紅色的部分不算做是一個匹配子集,即此正則內,可以獲取的就兩個 括號內的內容,其中第一個括號是 (/"[^(/"|//n)]*?/")

第2個括號是 ([^(/"|//n)]*?)  類似於 (?=abc)  ,括號也不算做一個子集

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章