Neko和Native的特定正则表达式失败

时间:2014-04-23 01:29:32

标签: regex haxe neko

所以我正在haxeflixel进行一些清理工作,我需要验证csv地图,所以我使用正则表达式检查它是否正常(不要提及结尾逗号,我知道这不是有效的csv,但我想允许它),我认为我有一个像样的正则表达式,它似乎在闪存上运行良好,但c ++崩溃,neko给了我这个错误:一个错误发生时运行pcre_exec .... 这是我的正则表达式,我很抱歉很长,但我不知道问题出在哪里...... ^(([ ]*-?[0-9]+[ ]*,?)+\r?\n?)+$ 如果有人知道可能会发生什么,我会很感激, 谢谢, 尼科

PS。我的正则表达式中可能存在检查csv的错误,但我可以解决这些错误,它有点令人愉快,我只是知道具体可能导致这个问题:)

编辑:嗯,我刚注意到这并没有发生在所有字符串上,一旦我把它缩小到什么字符串,我会张贴一个...至于我检查的是什么因为,它基本上只是为了确保没有奇怪的xml标头,或地图文件中的任何非整数值,基本上它应该验证这一点:

1,1,1,1

1,1,1,1

1,1,1,1

或者这个:

1,1,1,1,

1,1,1,1,

1,1,1,1,

但不是:

xml blahh blahh>

1,M,1,1-

1,1,B,1

1,1,1,1

XML>

(是的,我知道这不是有效的xml;))

编辑:它变得陌生: 所以我试图确定哪些字符串会崩溃它,虽然这仍然无法解释正常的地图崩溃,但它的确很奇怪,并且结果相同:

会发生什么: 这将失败一个.match()测试,但不会崩溃:

a

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

虽然这会使程序崩溃:

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

1,1,1,1,1,1,1,1,1,1,1,1,1,1,1

0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

1,*a*,1,1,1,1,1,1,1,1,1,1,1,1,1

1 个答案:

答案 0 :(得分:1)

老实说,你写过我见过的最糟糕的一个正念之一。实际上它看起来像是专门写得尽可能慢。我写这不是为了冒犯你,而是为了表达你需要学习写regexp的程度(提示:编写你自己的正则表达式引擎是一个很好的练习)。

针对你的问题,我猜它只是内存不足(内存非常密集)。我不确定为什么它只发生在pcre目标上(neko和cpp目标都使用pcre),但我想这是关于每个regexp在pcre中运行的内存限制或其他目标中的一些启发式来纠正这些错误的正则表达式。

我建议采用

的方式
~/^(( *-?[0-9]+ *,)* *-?[0-9]+ *,?\r?\n)*(( *-?[0-9]+ *,)* *-?[0-9]+ *,?\r?\n?)$/

那里,"〜/"最后" /"是haxe regexp标记。

我没有对它进行广泛测试,只是对你的样品进行了测试,但它应该完成这项工作(可能需要稍微调整一下)。

另外,作为提示,我建议您在运行任何正则表达式之前首先将文件拆分为行,这会降低内存使用量(或者您只需要在内存中保留部分文本)并且简化你的正则表达式。

我还要注意,因为无论如何你都需要解析csv(对于任何正确形成的输入,我猜你的数据中普遍存在),在实际解析时执行所有测试可能要快得多。

修改:问题的答案" 为什么它会占用如此多的内存"

嗯,这不是一个简短的话题,这也是我建议你编写自己的正则表达式引擎的原因。实现中存在一些差异,但通常假设regexp引擎的工作原理如下:

  1. 解析您的正则表达式并构建一个包含所有可能状态的图表(状态基本上是一个符号值和一些指向其他符号的链接)。
  2. 设置读指针和状态指针对的列表,当前状态列表,包括正则表达式初始状态和指向匹配字符串第一个字母的指针
  3. 设置指向符号字符串
  4. 的第一个符号的读指针
  5. 将状态指针设置为regexp的初始状态
  6. 从当前状态列表中取出一对并将其存储为当前状态和当前读指针
  7. 读取当前读指针下的符号
  8. 将其与当前状态有链接的状态中的符号匹配,并列出匹配的状态列表。
  9. 如果此列表中有最终的正则表达式状态,请转到12
  10. 对于此列表中的每个项目,将一对下一个读取指针(当前为+ 1)和项目添加到当前状态列表
  11. 如果当前状态列表为空,则返回false,因为字符串与正则表达式不匹配
  12. 转到6
  13. 这里是匹配regexp的最终状态,返回true,字符串匹配regexp。
  14. 当然,正则表达式引擎之间存在一些差异,其中一些引发了一些问题。当然,他们也有伪符号,分组,他们需要存储正则表达式和组匹配的位置,他们有前瞻和后观,并且还将参考分组,这使得它更复杂,并且使用更多的力量复杂的数据结构,但主要思想是一样的。所以,我们在这里,从算法中可以清楚地看到你的问题。关于你想要匹配的内容越不具体,引擎与状态图中的不同路径匹配相同子串的可能性越大,它将消耗的内存和处理器时间越多,指数就越多。 尝试模拟regexp引擎如何匹配字符串aaaaaab,ab,aa,aaaaaaaaa,aaaaaaaaaaaaaaaaaaaaaaaaaaaaa上的regexp(a + a +)+ b(不要尝试最后一个,在现代PC上计算需要数小时或数天。 )

    另外,值得注意的是,一些正则表达式引擎以不同的方式处理事情,因此它们可以正确处理这种情况,但总是有办法让regexp变得非常慢。

    另外需要注意的是,我可能对确切的记忆问题感到错误。这种情况下它可能也是处理器,在此之前它可能是内存/处理器的引擎限制,而不是内存系统的饥饿。