正则表达式是一项代价高昂的操作?似乎至少

时间:2016-01-08 10:37:11

标签: javascript regex string parsing

我正在为字符串编写正则表达式模式。字符串是常量类型/结构。我的意思是,它看起来像(这种格式不是那么重要,请看下一个例子) -

[Data Code Format]: POP N/N/N (N: object): JSON object data

这里N代表数字或数字。而且[]里面的是一组字符串块。但是,这种格式是不变的。

所以,我写了一个正则表达式 -

\s*((?:\S+\s+){1}\S+)\s*(?:\((?:.*?)\))?:\s*(\S*)\s*(\w+)

记住这个字符串示例 -

%DATA-4-JSON: POP 0/1/0 (1: object): JSON object data

它完美无缺,但是,我在regex101.com看到的是成功匹配。但是,它实现了330步。

截图 -

image

我的问题是,它采取了330步骤来达到这个目标(至少在我的脑海里我觉得它很重),我猜这可以用if-else和其他与较小的比较来实现步骤对吗?

我的意思是,正则表达式字符串解析如此沉重?我需要解析的10000个字符串的330步骤会很重吗?

1 个答案:

答案 0 :(得分:7)

当您使用正则表达式时,如果您使用回溯,它们可能会很昂贵。当您使用具有可能彼此匹配的后续模式的量词时(如果它们之间的模式可能匹配空字符串(通常使用*{0,x}?量词),回溯可能会对你造成不好的伎俩。

你的正则表达式有什么不好?

轻微的性能问题是由不必要的非捕获组(?:\S+\s+){1}引起的。它可以写成\S+\s+,它已经减少了步数(a bit, 302 steps)。但是,最糟糕的是\S匹配:分隔符。因此,正则表达式引擎必须尝试许多可能的路线来匹配您预期匹配的开始。将\S+\s+\S替换为[^:\s]+\s+[^:\s]+step amount will decrease to 159

现在,来(?:\((?:.*?)\))? - 删除不必要的内部非捕获组会给出另一个小的改进(148 steps),并且用一个否定的字符类替换.*?会得到另一个提升({ {3}})。

我现在就用这个​​:

\s*([^:\s]+\s+[^:\s]+)\s*(?:\([^()]*\))?:\s*(\S*)\s*(\w+)

如果最初的\s*是强制性的,那么这将是另一项增强功能,但您会有不同的匹配。