忽略子字符串的Javascript正则表达式
背景: 我在这个主题上找到了类似的S.O.帖子,但我没能让它适合我的场景。如果这是一个受骗者,请提前预约 我的意图: 把每一个英语单词放在一个字符串中,并将其转换为html超链接。此逻辑只需忽略以下标记:忽略子字符串的Javascript正则表达式,javascript,regex,Javascript,Regex,背景: 我在这个主题上找到了类似的S.O.帖子,但我没能让它适合我的场景。如果这是一个受骗者,请提前预约 我的意图: 把每一个英语单词放在一个字符串中,并将其转换为html超链接。此逻辑只需忽略以下标记:,, 这是我到目前为止所拥有的。正如我所期望的那样,它将英语单词转换为超链接,但对html标记没有忽略逻辑(这就是我需要您帮助的地方): text=text.replace(/\b([A-Z \-A-Z]+)\b/g,“”; 输入/输出示例: 样本输入: this <b>is<
,
,
这是我到目前为止所拥有的。正如我所期望的那样,它将英语单词转换为超链接,但对html标记没有忽略逻辑(这就是我需要您帮助的地方):
text=text.replace(/\b([A-Z \-A-Z]+)\b/g,“”;
输入/输出示例:
样本输入:
this <b>is</b> a test
这是一个测试
预期产出:
<a href="?q=this">this</a> <b><a href="?q=is">is</a></b> <a href="?q=a">a</a> <a href="?q=test">test</a>
谢谢。除了重新设置HTML之外,我的方法是分两步进行:
- 首先,以这样或那样的方式提取标签外的文本
- 然后只把这些转化成文本,其他的都保持不变
innerHTML
的性能增益,并且在查找匹配项时不必弄乱HTML字符串:
function findMatchAndReplace(node, regex, replacement) {
var parent,
temp = document.createElement('div'),
next;
if (node.nodeType === 3) {
parent = node.parentNode;
temp.innerHTML = node.data.replace(regex, replacement);
while (temp.firstChild)
parent.insertBefore(temp.firstChild, node);
parent.removeChild(node);
} else if (node.nodeType === 1) {
if (node = node.firstChild) do {
next = node.nextSibling;
findMatchAndReplace(node, regex, replacement);
} while (node = next);
}
}
输入:
<div id="foo">
this <b>is</b> a test
</div>
这是一个测试
过程:
findMatchAndReplace(
document.getElementById('foo'),
/\b\w+\b/g,
'<a href="?q=$&">$&</a>'
);
查找匹配位置(
document.getElementById('foo'),
/\b\w+\b/g,
''
);
输出(为清晰起见添加了空格):
这里是另一个JavaScript方法
var StrWith_WELL_FORMED_TAGS = "This <b>is</b> a test, <br> Mr. O'Leary! <!-- What about comments? -->";
var SplitAtTags = StrWith_WELL_FORMED_TAGS.split (/[<>]/);
var ArrayLen = SplitAtTags.length;
var OutputStr = '';
var bStartWithTag = StrWith_WELL_FORMED_TAGS.charAt (0) == "<";
for (var J=0; J < ArrayLen; J++)
{
var bWeAreInsideTag = (J % 2) ^ bStartWithTag;
if (bWeAreInsideTag)
{
OutputStr += '<' + SplitAtTags[J] + '>';
}
else
{
OutputStr += SplitAtTags[J].replace (/([a-z']+)/gi, '<a href="?q=$1">$1</a>');
}
}
//-- Replace "console.log" with "alert" if not using Firebug.
console.log (OutputStr);
var StrWith_-WELL_-FORMED_-TAGS=“这是一个测试,
O'Leary先生!”;
var SplitAtTags=strw,带有成型良好的标签。拆分(/[]/);
var ArrayLen=SplitAtTags.length;
var OutputStr='';
var bStartWithTag=StrWith_-WELL_-FORMED_-TAGS.charAt(0)=“你在和DOM合作吗?如果是这样的话,你就不应该把HTML字符串搞得乱七八糟;相反,您应该按照预期使用DOM API。是的,使用DOM。由于此特定项目的要求,操作字符串以获得性能。在这里我不想旁敲侧击,但我用它作为性能的参考:谢谢J-P,一个聪明的解决方案。很抱歉在我的问题中没有澄清,尽管我通过InnerHTML设置了DOM节点,但我原始文本的原始源来自AJAX调用,因此我没有DOM节点(正如您的第一个参数所要求的那样)。@mrscott,您仍然可以从AJAX响应中获得DOM结构<代码>函数toDom(str){var d=document.createElement('div');d.innerHTML=str;return d;}
谢谢J-P。这确实有效,但我对我发布的解决方案运行了一些性能测试,发现在包含一组稀疏的和标记的大量文本上,您的方法将慢10倍左右(这模仿了我面临的真实情况)。很好的解决方案Brock,但我希望有更简洁的东西。我想我已经找到了解决方案-我会很快发布它。
<div id="foo">
<a href="?q=this">this</a>
<b><a href="?q=is">is</a></b>
<a href="?q=a">a</a>
<a href="?q=test">test</a>
</div>
var StrWith_WELL_FORMED_TAGS = "This <b>is</b> a test, <br> Mr. O'Leary! <!-- What about comments? -->";
var SplitAtTags = StrWith_WELL_FORMED_TAGS.split (/[<>]/);
var ArrayLen = SplitAtTags.length;
var OutputStr = '';
var bStartWithTag = StrWith_WELL_FORMED_TAGS.charAt (0) == "<";
for (var J=0; J < ArrayLen; J++)
{
var bWeAreInsideTag = (J % 2) ^ bStartWithTag;
if (bWeAreInsideTag)
{
OutputStr += '<' + SplitAtTags[J] + '>';
}
else
{
OutputStr += SplitAtTags[J].replace (/([a-z']+)/gi, '<a href="?q=$1">$1</a>');
}
}
//-- Replace "console.log" with "alert" if not using Firebug.
console.log (OutputStr);