【发布时间】:2014-11-29 01:18:20
【问题描述】:
我正在用 C# 编写一个用于一些数据处理的程序,在做了一些分析之后,我发现我使用的正则表达式是最大的瓶颈。它们占用了整个算法大约 80% 的时间,这不仅仅是解析,所以我决定改为手动解析数据。
格式相当简单,我基本上是在解析=XXX+YYY 形式的简单算术表达式,其中XXX 和YYY 是术语,+ 表示一组有限的运算符之一可以应用于这些条款。总是只有两个术语和一个运算符,尽管术语可以用几种不同的方式表示。
到目前为止,我的方法基本上是编写一个类似于(matchXXX)([+-*/...])(matchYYY) 的正则表达式,然后在每个操作数上应用另一个正则表达式以查看它们是什么类型。我在编写高性能解析器方面并没有太多经验。我只在 Haskell 中使用过 Parsec,它有一种非常独特的方法,并且可能需要大量工作才能实现。
那么问题来了,为这种表达式编写解析器的好方法是什么?是否有一种在大多数情况下都行之有效的通用方法?
我不是在寻找解析器生成器。我需要的是一个可以手动实现的简单解决方案。
更新:目前最慢的正则表达式是([A-Z]+\d+)([+\-*/])([A-Z]+\d+)
【问题讨论】:
-
为什么不直接使用
String.Split方法,将有限的字符集作为分隔符传递? -
如果不是太复杂,您能展示一下您的正则表达式吗?
-
如果您使用traps,正则表达式可能会变慢,但优化后它们也可能会变快。另外,不要忘记使用
RegexOptions.Compiled。发布您的正则表达式,以便我们查看它是否有问题。 -
@Dmitry 如果有办法查看拆分发生在哪个字符上,我可以这样做,但是查看 API,那里似乎没有选项。
-
如果您也需要运营商的
char,请尝试使用String.IndexOfAny和String.Substring。