所以我正在haxeflixel中进行一些清理,我需要验证csv映射,所以我使用正则表达式来检查它是否正常(不要提及结束逗号,我知道这不是有效的csv,但我想允许它),我认为我有一个不错的正则表达式来做这件事,它似乎在flash上运行良好,但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等等>
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
老实说,您编写了我见过的最糟糕的regexp之一。实际上,它看起来是专门写得尽可能慢的。我写这篇文章并不是为了冒犯您,而是为了表达您需要学习如何编写regexp(提示:编写自己的regexp引擎是一个很好的练习)。
说到你的问题,我想它只是内存不足(它非常占用内存)。我不知道为什么它只发生在pcre目标上(neko和cpp目标都使用pcre),但我想这是关于在pcre中运行的每个regexp的内存限制,或者是其他目标中的一些启发式方法来纠正这种写错的regexp。
我建议一些类似的东西
~/^(( *-?[0-9]+ *,)* *-?[0-9]+ *,?r?n)*(( *-?[0-9]+ *,)* *-?[0-9]+ *,?r?n?)$/
其中,"~/"和最后一个"/"是haxe regexp标记。
我并没有对它进行广泛的测试,只是在你的样本上运行了一次,但它应该可以完成任务(可能需要一些调整)。
此外,作为一个提示,我建议您在运行任何regexp之前先将文件拆分成行,这将降低内存使用率(或者您只需要在内存中保存一部分文本)并简化regexp。
我还要注意的是,由于您无论如何都需要解析csv(对于任何格式正确的输入,我想这在您的数据中很普遍),因此在实际解析时进行所有测试可能会快得多。
编辑:问题"为什么它会吃掉这么多内存"的答案
好吧,这不是一个简短的主题,这就是为什么我建议您编写自己的regexp引擎。实现中存在一些差异,但通常假设regexp引擎的工作方式如下:
- 解析正则表达式,并构建一个所有可能状态的图(状态基本上是一个符号值和指向后面其他符号的许多链接)
- 设置读取指针和状态指针对的列表,即当前状态列表,由regexp初始状态和指向匹配字符串第一个字母的指针组成
- 设置指向符号字符串的第一个符号的读取指针
- 将state poiter设置为regexp的初始状态
- 从当前状态列表中取出一对,并将其存储为当前状态和当前读取指针
- 在当前读取指针下读取符号
- 将其与当前状态具有链接的状态中的符号进行匹配,并生成匹配状态的列表
- 如果此列表中有最后一个regexp状态,则转到12
- 对于该列表中的每个项目,将一对下一个读取指针(当前+1)和项目添加到当前状态列表
- 如果当前状态列表为空,则返回false,因为字符串与regexp不匹配
- 转到6
- 在匹配的regexp的最终状态下,返回true,字符串匹配regexp
当然,正则表达式引擎之间存在一些差异,其中一些引擎消除了一些问题。当然,他们也有伪符号,分组,他们需要存储正则表达式和匹配的组的位置,他们有前瞻和后向,还有分组引用,这使它变得更复杂(相当谦虚),并迫使使用更复杂的数据结构,但主要思想是一样的。所以,我们到了,从算法中可以清楚地看到您的问题。您对想要匹配的内容越不明确,引擎将同一子字符串匹配为状态图中不同路径的机会就越大,它将消耗的内存和处理器时间就越多。尝试对正则表达式引擎如何在字符串aaaaa-b、ab、aa、aaaaaaaaaa上匹配正则表达式(a+a+)+b进行建模(不要尝试最后一个,在现代电脑上计算需要数小时或数天时间)
此外,值得注意的是,一些regexp引擎以一种稍微不同的方式进行操作,因此它们可以正确地处理这种情况,但总有一些方法会使regexp变得非常慢。
另一件需要注意的事情是,我可能对确切的记忆问题有错误的看法。在这种情况下,可能也是处理器,在此之前,可能是内存/处理器的引擎限制,而不是系统内存不足。