看似不可能完成的任务。我有一个服务器输出,其中包含 <pre>
内的转储。不幸的是,我碰巧转储了一个包含一些 html 标签的文件。我需要转换任何内部 </pre>
HTML 实体,以便当我将数据附加到 DOM 时结构不会被破坏:
<pre>
...
echo '<pre>'
cat gcc.log
echo '</pre>'
...
</pre>
但是有一个明显的规则 - 总会有 echo '
之前<pre>
或</pre>
。可能不完全是echo '</pre>
不过。
基于此,我构造了已经相当复杂的正则表达式:
<pre> - The beginning tag
([\s\S]*?) - Any characters including new lines
(?:(echo[^\n]+) - Echo and anything but new line
(<pre>|<\/pre>|<\/xmp>|<xmp>)) - The enclosing tags
([\s\S]*?) - More random characters
<\/pre>
问题是,只要有两个 </pre>
在代码中,正则表达式仅匹配第一个,并将第二个视为随机字符 - ([\s\S]*?)
.
如何使正则表达式首先尝试匹配显式字符,然后匹配 .*?
东西?
您可以在 http://regex101.com 现场尝试该功能。
哦,我真的无法在服务器上修复它
最佳答案
这可能有效(假设标签在引号内并且引号特别平衡):
var html = "<pre>\n ...\n echo '<pre>'\n cat gcc.log\n echo '</pre>'\n ...\n</pre>";
html = html.replace(/(<pre[^>]*>)((?:(?=((["'])(?:(?=(\\.|[^\\"']+|(?!\5)["']))\4)*\5|[^'<]+|<(?!\/pre>)))\3)*)<\/pre>/g,
function(_, g1, g2) {
g2 = g2.replace(/</g, '<');
g2 = g2.replace(/>/g, '>');
return g1 + g2 + '</pre>';
}
);
console.log(html);
此模式使用以下技巧模拟原子组:(?>pattern)
=> (?:(?=(pattern))\1)
使用以下事实:前瞻的内容自然是原子的,以避免灾难性的回溯。
关于javascript - 匹配 <pre> 内的 <pre> 和 </pre>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23716852/