2010-06-26 19 views
1
  1. 我應該使用RegularExpressions來做到這一點嗎?
  2. 能夠構造的結果可查詢,IEnumerable的,等

我有一個文件,我不能改變它是如何產生的。我希望創建一個解析器類來提取所有數據。理想情況下,我想然後使用這個類來打開文件並讓它返回一個我可以使用的可查詢數組類型結構。在C中解析一個自定義文件#

的數據結構是這樣的:

["Table"] = { 
    ["Text"] = { 
     ["Number"] = { 
      "Item", --[1] 
      "Item", --[2] 
      "Item", --[3] 
     }, 
    --repeat-- 
Note that the actual file has line brakes, tab, etc. (\n\t\t) 
As you will see the patters I use take this into account 
to get different levels. 

我有一個對VB6編寫了這個非常文件,但正則表達式中,7種圖案的1不起作用:

@"^\t\[""([\s\S]*?)""] = {([\s\S]*?)^\t},$ 

這應該將最高級別[「表格」]分組到他們自己的比賽中。但它返回0並且很慢。如果我把$ sign拿出來,它也會返回所有的子節點。這是阻止我使用正則表達式執行此操作的唯一因素。

另一種選擇是隻是逐行解析我猜。我確信我可以在給定的時間內解決這個問題,但是我希望在我走另一條路之前聽到其他意見。

有什麼想法?

+0

您試圖從中提取的數據在哪裏?每個分組中的表格,文本,數字,項目,1,2,3是不變的值? – Andy 2010-06-26 03:38:58

回答

1

我猜你的結構是相關的Lua。至少從任何一天Lua應該可讀的外觀來看。如果我是正確的,你可能想看看luainterface

也有一些其他的與示例代碼的問題在這裏:Parse a Lua DatastructureRead nested Lua table

+2

這是Lua。我最終定製了這個http://youpvp.com/blog/post/LuaParse-C-parser-for-World-of-Warcraft-saved-variable-files.aspx – Dan 2010-06-28 16:02:27

+0

很好找,以前還沒有看過: ) – Don 2010-06-28 17:59:00

1

隨你的直覺走。正則表達式是解決這個問題的正確方法。如果你能張貼了一份樣品,我可以幫你寫一個正則表達式匹配任何你想要的:-)

一種方式輕鬆快速測試你的正則表達式是去http://rubular.com/

這表明你的比賽對你的樣品進行快速檢測。讓你快速調整你的表情。

+1

Rubular是一個漂亮的網站...感謝您指出。 – JasCav 2010-06-26 04:03:38

3

我會遠離正則表達式,如果你想對這樣的文件做任何真實世界的解析,你會很快遇到與正則表達式的巨大的不可解析的問題,例如處理正確的嵌套(假設你的文件可以有多層次的嵌套)和正確性會導致你非常頭痛。有許多模式可能會導致任何正則表達式處理器幾乎看起來像一個無限循環,並且永遠不會結束(或者至少在任何合理的時間內),並且真正編寫這樣一個簡單的解析器應該很快並且導致更好的調試,性能和可維護性等

+0

+1 - PARSER可能更正確。獲得一個允許你提出「適當的語法」,這對於複雜的語法來說更好。 – TomTom 2010-06-26 05:29:43

0

不要使用正則表達式 - 得到適當的解析器,你可以把一個語法文件。與REGEX相比,這可以輕鬆進行更復雜的分析。

0

問題1實際上自己回答。事實上,這是在很多情況下應避免使用正則表達式的兩大理由的教科書示例。

  • 你繼承了工作正則表達式,但現在它需要進行調整,沒有人在你的店鋪有必要的專業知識。

  • 數據具有遞歸或層次結構,正則表達式特別適合用於某些情況。

你的正則表達式通過作弊解決了遞歸問題;它使用每行的領先空白的長度來推斷哪個分隔符與哪個分隔符一致。你可能正確使用.NET的遞歸匹配功能,但它會非常非常醜陋。所以讓我們看看我們可以用你的所得做什麼。

@"^\t\[""([\s\S]*?)""] = {([\s\S]*?)^\t},$" 

您性能問題幾乎可以肯定是由於該第二[\s\S]*?,可呈現,順便說一下,應該是.*?與單線模式設置;只有JavaScript需要[\s\S]黑客。但是無論你寫什麼,你都要求它做太多的工作。這是我會怎麼做:

@"^\t\[""([^""]*)""\] *= *{(?>.*\n)*?\t}," // Multiline ON, Singleline OFF 

你在哪裏,用[\s\S]*?匹配的一個字符時,我在與(?>.*\n)*?一時間全系列匹配。不情願的量詞是非常方便的,但是如果你過度勞累他們,你可以和他們一樣對付貪婪的量詞。

我仍然在開始時使用^定位點,但我不必在其他地方使用定位點,因爲我明確地匹配了所有換行符。儘管爲了清楚起見我在本例中使用了\n,但我通常使用(?:\r\n|[\r\n])來匹配三種最常用的行分隔符:\r\n(Windows),\r(較老的Mac)和\n(Unix/Linux/OSX)中的任何一個。