我正在为字符串编写正则表达式模式。字符串是常量类型/结构。我的意思是,它看起来像(这种格式不是那么重要,请看下一个例子) -
[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步。
截图 -
我的问题是,它采取了330步骤来达到这个目标(至少在我的脑海里我觉得它很重),我猜这可以用if-else
和其他与较小的比较来实现步骤对吗?
我的意思是,正则表达式字符串解析如此沉重?我需要解析的10000个字符串的330步骤会很重吗?
答案 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*
是强制性的,那么这将是另一项增强功能,但您会有不同的匹配。