過程真是艱苦啊,對文本結構分析的不全面,一度讓我以爲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) ,括號也不算做一個子集