仅当不在 html 属性中匹配时提高正则表达式性能

Increase regex performance when matching only if not in html attribute

TYPO3 在使用 Typoscript 时阻止呈现包含 13 个以上内容元素的页面:

brandReplacing {
    stdWrap {
        replacement {
            10 {
                search = ®(?=[<]*(?:<[^>]*>[^<]*)*$)
                replace = <sup>®</sup>
                useRegExp = 1
            }
        }
    }
}

因为这个正则表达式甚至需要 118 个步骤来完成这个短 example(需要的步骤呈指数级增长/比如 83000 个步骤需要另外两个属性)。总而言之,正则表达式工作正常,但也 "huge".

有没有人知道如何减少执行正则表达式所需的步骤(性能)并可能还排除 ®-已经用 <sup>- 标签包裹的符号?或者有没有更好的办法解决这个TYPO3面的问题?

上面的正则表达式:

®(?=[<]*(?:<[^>]*>[^<]*)*$)

html代码:

<img title="Copyright replacement incorrect ®" src="/fileadmin/filexyz.png">
<h1>Copyright replacement correct: ®</h1>
Also correct replacement here: ®
Maybe NOT here: <sup>®</sup>

我没有分析你的正则表达式来准确地找出发生了什么,但显然回溯正在消耗资源。还有其他方法可以结束一种模式以防止它进一步发展:遵循规则。

定义属性及其占位符应该有一些规则。我附带了两条规则,您可以稍后将其添加到它们中(参见当 ® 位于属性值内时):

  1. 可能还有另一个 attr = " value " 紧随其后 由目前的。匹配一直持续到引擎看到 > 没有 跳过任何 <>[^"<>]*"(\s\s*[\w-]+="[^<>]*>
  2. 或者它可能是最后一个要到达右大括号的属性 >\/?>

正则表达式:

(®)(?!([^"<>]*"(\s\s*[\w-]+="[^<>]*>|\s*\/?>)))

Live demo

如果将它与您的两个正则表达式进行比较,您会发现它的速度有多快。捕获的 ®s 与之前的位置完全相同。它几乎不会匹配错误的位置。

失败案例:

不匹配 ®:

  • 如果在文字文本中紧跟 " string="...>。例如:
<div>® character" some-chars-here="...."  /></div>
  • 如果在文字文本中紧跟 " />" >。例如:
<div>®   "        /></div>

我认为这很少发生。