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

时间:2013-06-15 13:38:16

标签: javascript html regex

我想使用正则表达式来标记一些可能跨越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>

在close标签之间有一个空的<strong>元素也没关系。使用任何Javascript库都没问题。它可以是特定于浏览器的。

2 个答案:

答案 0 :(得分:2)

我会在两次传递中完成,首先查找整个句子,然后将每个单词放在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>')
});

Demonstration

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

答案 1 :(得分:1)

我希望有人能想出一个更简单的解决方案。这就是我想出来的。 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);