在 HTML 标记中避免灾难性回溯
Escape catastrophic backtracking in HTML markup
正如我在标题中所说,我的数据集是标记的,看起来有点像这样
<!DOCTYPE html>
<html>
<head>
<title>page</title>
</head>
<body>
<main>
<div class="menu">
<img src=mmayboy.jpg>
<p> Whosebug is good </p>
</div>
<div class="combine">
<p> i have suffered <span>7</span></p>
</div>
</main>
</body>
</html>
我的正则表达式引擎尝试分别匹配以下每个节点块,即我可以尝试匹配 combine
或 menu
。一张照片,这就是我的正则表达式引擎的样子,尽管我深入了解了它下面的内部结构。
/(<div class="menu">(\s+.*)+<\/div>(?:(?=(\s+<div))))/
它试图深入该标记并获取所需的节点块。就这些。至于内部结构,我们开始吧
/
(
<div class="menu"> // match text that begins with these literals
(
\s+.*
)+ /* match any white space or character after previous. But the problem is that this matches up till the closing tag of other DIVs i.e greedy. */
<\/div> // stop at the next closing DIV (this catches the last DIV)
(?: // begin non-capturing group
(?=
(
\s+<div
) /* I'm using the positive lookahead to make sure previous match is not followed by a space and a new DIV tag. This is where the catastrophic backtracking is raised. */
)
)
)
/
我在评论中缩进了它,以帮助任何愿意提供帮助的人。我还从博客中寻找解决方案,the manual 他们 说这是由具有太多可能性的表达式引起的,可以通过减少结果的机会来补救,即 +?
而不是 *
但尽我所能,我无法将其中的任何一个应用到我当前的困境中。
(\s+.*)+
大概可以简化为
[^]*?
这应该可以防止灾难性的回溯。整体简化:
/<div class="menu">[^]*?<\/div>/
不过,您是否考虑过使用 an HTML parser?
var parser = new DOMParser();
var doc = parser.parseFromString(data, 'text/html');
var menu = doc.getElementsByClassName('menu')[0];
console.log(menu.innerHTML);
正如我在标题中所说,我的数据集是标记的,看起来有点像这样
<!DOCTYPE html>
<html>
<head>
<title>page</title>
</head>
<body>
<main>
<div class="menu">
<img src=mmayboy.jpg>
<p> Whosebug is good </p>
</div>
<div class="combine">
<p> i have suffered <span>7</span></p>
</div>
</main>
</body>
</html>
我的正则表达式引擎尝试分别匹配以下每个节点块,即我可以尝试匹配 combine
或 menu
。一张照片,这就是我的正则表达式引擎的样子,尽管我深入了解了它下面的内部结构。
/(<div class="menu">(\s+.*)+<\/div>(?:(?=(\s+<div))))/
它试图深入该标记并获取所需的节点块。就这些。至于内部结构,我们开始吧
/
(
<div class="menu"> // match text that begins with these literals
(
\s+.*
)+ /* match any white space or character after previous. But the problem is that this matches up till the closing tag of other DIVs i.e greedy. */
<\/div> // stop at the next closing DIV (this catches the last DIV)
(?: // begin non-capturing group
(?=
(
\s+<div
) /* I'm using the positive lookahead to make sure previous match is not followed by a space and a new DIV tag. This is where the catastrophic backtracking is raised. */
)
)
)
/
我在评论中缩进了它,以帮助任何愿意提供帮助的人。我还从博客中寻找解决方案,the manual 他们 说这是由具有太多可能性的表达式引起的,可以通过减少结果的机会来补救,即 +?
而不是 *
但尽我所能,我无法将其中的任何一个应用到我当前的困境中。
(\s+.*)+
大概可以简化为
[^]*?
这应该可以防止灾难性的回溯。整体简化:
/<div class="menu">[^]*?<\/div>/
不过,您是否考虑过使用 an HTML parser?
var parser = new DOMParser();
var doc = parser.parseFromString(data, 'text/html');
var menu = doc.getElementsByClassName('menu')[0];
console.log(menu.innerHTML);