我有一个正则表达式,用于匹配@users标签。
我使用lokarround断言,让标点符号和空格字符包围标签。
这增加了复杂性,有一种表示html的bbcode。
我有两种类型的bbcode,内联(^B
粗体^b
)和块(^C
中心^c
)。
内联字符必须直通以到达上一个或下一个字符。
就像标点符号一样,这些块也被允许围绕标签。
我做了一个有效的正则表达式。我现在想做的是减少它不会匹配的每个角色的步数。
起初我以为我可以做一个正则表达式,只寻找@
,当它找到时,它会开始寻找lookarrounds,这种方法不需要内联bbcode,但是由于lookbehind无法量化,因此自我无法在其中添加((\^[BIUbiu])++)*
,从而产生了更多步骤。
如何以更少的步骤使我的正则表达式更有效?
这是它的简化版,在Regex101链接中有完整的正则表达式。
(?<=[,\.:=\^ ]|\^[CJLcjl])((\^[BIUbiu])++)*@([A-Za-z0-9\-_]{2,25})((\^[BIUbiu])++)*(?=[,\.:=\^ ]|\^[CJLcjl])
答案 0 :(得分:1)
经验法则:
如果出现以下情况,请勿让引擎尝试匹配每个单个字符 有一些界限。
引用最初来自此答案。遵循正则表达式会因为最外侧交替的左侧(从〜20000到〜900)而极大地减少了步长:
(?:[^@^]++|[@^]{2,}+)(*SKIP)(*F)
|
(?<=([HUGE-CHARACTER-CLASS])|\^[cjleqrd])
(\^[34biu78])*+@([a-z\d][\w-.]{0,25}[a-z\d])(\^[34biu78])*+(?=(?1))
实际上,我不太关心regex101报告的步骤数,因为在您自己的环境中这不是正确的,并且不清楚某些步骤是真实的还是遗漏了哪些步骤。但是在这种情况下,由于正则表达式的逻辑很明确,并且差异很大,所以很有意义。
逻辑是什么?
我们首先尝试匹配可能根本不需要的内容,将其扔掉,然后寻找可能与我们的模式匹配的部分。 [^@^]++
最多可匹配@
或^
符号(所需字符),而[@^]{2,}+
可防止引擎在发现错误之前采取额外的措施。因此,我们使其尽快失效。
您可以使用i
标志代替定义大写字母形式的字母(但是可能会产生一些影响)。