如何优化正则表达式以检查包含锚标记的文本



我有一个有效的正则表达式来检查只有锚标记的文本,但给出结果需要太多时间。我需要在哪里更改表达式以优化它?

当只有一个锚标记时,正则表达式工作正常,但当有多个锚标记并且根据正则表达式测试字符串错误时,则无法正常工作。

下面是我的正则表达式

/^([^<]*(<a href="([^"]+)">([^<]+)</a>)*)*$/g
True :: /^([^<]*(<a href="([^"]+)">([^<]+)</a>))/g.test('Test a <a href="https://www.google.com">test</a> hgygiuu dfgdfg')
False ::/^([^<]*(<a href="([^"]+)">([^<]+)</a>))/g.test('Test a <a href="https://www.google.com">test</a> hgygiuu dfgdfg <b') //due to non matching '<b'
True :: /^([^<]*(<a href="([^"]+)">([^<]+)</a>))/g.test('Test a <a href="https://www.google.com">test</a> hgygiuu dfgdfg Test a <a href="https://www.google.com">test</a> hgygiuu dfgdfg')
False (very slow) :: /^([^<]*(<a href="([^"]+)">([^<]+)</a>))/g.test('Test a hyperlink with long text <a href="https://www.google.com">test</a> hgygiuu dfgdfg Test a <a href="https://www.google.com">test</a> hgygiuu dfgdfg <span')

听起来您正在尝试验证输入文本是否可以与某些 HTML连接。如果可以更改输入文本的插入位置,使其单独插入,而不是作为较大 HTML 字符串的一部分插入,则验证将容易得多。

例如,而不是

html += inputStr

做类似的事情

html += '<div class="input-container"></div>';

然后,在将 HTML 插入文档后,分配给该.input-containerinnerHTML

document.querySelector('.input-container').innerHTML = inputStr;

这将确保不匹配或不完整的标记被忽略,而不是导致问题。正如您在以下代码片段中看到的,尽管内部 DOM 字符串似乎已设置为foo<b>bar,但<b部分被完全忽略,因为它不是一个格式正确的标签,并且>bar中的>被解释为文本括号,而不是标签的一部分。

container.innerHTML = 'foo<b';
container.innerHTML += '>bar';
<div id="container"></div>

如果使用此方法插入输入字符串,则验证输入会容易得多。您所要做的就是将输入字符串解析为元素,并检查该元素包含的唯一标记是否为<a>s 和hrefs:

const verify = (str) => {
const { body } = new DOMParser().parseFromString(str, 'text/html');
return [...body.children].every(
child => child.tagName === 'A' && child.hasAttribute('href') && child.attributes.length === 1
);
};
console.log(
verify('foo'),
verify('foo <a href="link">link</a>'),
verify('foo <a href="link" onclick="evil">link</a>')
);

尽可能避免尝试使用正则表达式解析 HTML。

确保在您控制的环境中执行此操作(例如在Node 中),而不仅仅是在客户端上,因为您不能信任在客户端上完成的任何验证。

您可以在正则表达式下面尝试。我希望它能帮助你。

/^<a.*>.*</a>/

最新更新