如何使用Javascript在HTML中标记一些跨越多个标签的文本

How can I markup some text spanning multiple tags in HTML using Javascript?

本文关键字:跨越 标签 文本 Javascript 何使用 HTML      更新时间:2023-09-26

我想使用regexp来标记一些文本,这些文本可能跨越HTML中任何数量的标签。

交货。给定正则表达式"brown' fox.*lazy' dog"

<div>The quick brown <a href="fox.html">fox</a></div>
<div>jumps over</div>
<div>the lazy <a href="dog.html">dog</a></div>

将被转换为

<div>The quick <strong>brown </strong><a href="fox.html"><strong>fox</strong></a></div>
<div><strong>jumps over</strong></div>
<div><strong>the lazy </strong><a href="dog.html"><strong>dog</strong></a></div>

在关闭标记之间有一个空的<strong>元素也可以。使用任何Javascript库都可以。

我会分两步完成,首先定位整个句子,然后将每个单词放在strong中。

由于我觉得手工构建正则表达式不实用,所以我生成它们:

var sentence = 'the quick brown fox jumps over the lazy dog';
var r1 = new RegExp(sentence.split(' ').join('''s*(<[^>]*>''s*)*'), 'i');
var r2 = new RegExp('('+sentence.split(' ').join('|')+')', 'gi');
str = str.replace(r1, function(sentence) {
  return sentence.replace(r2, '<strong>$1</strong>')
});

示范

我不能保证它在所有情况下都有效,但我现在没有看到任何失败的情况。这段代码确保句子是完整的,不包括标签外的单词,并且单词的顺序是正确的。

我希望有人能想出一个更简单的解决方案。这是我想到的。http://jsbin.com/usapej/4

// Initial values
var html = $('#text').html();
var re = /brown fox(.|['r'n])*lazy dog/;
var openTag = "<strong>";
var closeTag = "</strong>";
// build a list of tags in the HTML
var tagRe = /<[^>]*>/g;
var matches = [];
var tagResult;
var offset = 0;
while((tagResult = tagRe.exec(html)) !== null) {
  // Make the index relative to the start of the string w/o the tags
  tagResult.index -= offset;
  offset += tagResult[0].length;
  matches.push(tagResult);
}
// put our markup in the HTML
var text = $('#text').text();
var result = re.exec(text);
text = text.substring(0, result.index) + openTag + result[0] + closeTag + text.substring(result.index + result[0].length);
// Put the original tags back in surrounded by our close and open tags if it's inside our match
offset = 0;
var p;
for(var i = 0; i < matches.length; i++) {
  var m = matches[i];
  if(m.index <= result.index) {
    text = text.substring(0, m.index + offset) + m[0] + text.substring(m.index + offset);
    offset += m[0].length;
  } else if(m.index > result.index + result[0].length) {
    p = m.index + offset + openTag.length + closeTag.length;
    text = text.substring(0, p) + m[0] + text.substring(p);
    offset += m[0].length;
  } else {
    p = m.index + offset + openTag.length;
    var t = closeTag + m[0] + openTag;
    text = text.substring(0, p) + t + text.substring(p);
    offset += t.length;
  }
}
// put the HTML back into the document
$('#text').html(text);