2010-06-26 31 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)中的任何一个。