用一部分替换重复的字符串

时间:2012-02-02 17:19:30

标签: javascript regex replace

假设我有以下文字:(示例)

<table>
  <tr>
    <td>
      <span>col1</span>
    </td>
    <td>col2</td>
  </tr>
  <tr>
    <td>text1</td>
    <td>
      <span>text2</span>
    </td>
  </tr>
</table>

我想用<span>%</span>替换所有%,我想出了这样的解决方案:

replace(/<span>(.*)<\/span>/gi, function(full, text){return text;})

它从第一个span替换到最后一个只出现一次,因此我的表的整个结构搞砸了。

我怎么能告诉JS用正确的一个替换每个事件而不是一次性替换所有事件?解决方案显然需要在Javascript中。我希望我的例子不是太“简单”,并且可以避免任何混淆。

2 个答案:

答案 0 :(得分:3)

.*贪婪,所以会愉快地匹配</span>...<span>。将其替换为非贪婪的[\s\S]*?,但(与.不同)匹配任何字符,包括换行符。

/<span>([\s\S]*?)<\/span>/gi

更好的是,将其正确解析为DOM,然后在那里更改跨度。

编辑:

不是学习如何用正则表达式解析HTML,而是花时间学习更适合这个问题的DOM操作工具。

要解析HTML,您可以

var container = document.createElement('DIV');
container.innerHTML = myStringOfHTML;

然后

container.getElementsByTagName('SPAN')

将获得所有SPAN。

查找仅包含文本节点的内容很简单:

var spans = container.getElementsByTagName('SPAN');
for (var i = 0, n = spans.length; i < n; ++i) {
  var span = spans[0];
  // do work here
}

将孩子折叠成父母,

var spans = document.getElementsByTagName('SPAN');
for (var i = 0, n = spans.length; i < n; ++i) {
  var span = spans[0];
  while (span.firstChild) {
    span.parentNode.insertBefore(span, span.firstChild);
  }
  span.parentNode.removeChild(span);
}

答案 1 :(得分:0)

我认为HTML和正则表达式在一般情况下并不顺利,而且@MikeSamuel有一个很好的使用DOM的解决方案,但使用正则表达式(在这种情况下)非常简单。

var text = '<td>Hello</td> <td><span>WORLD</span></td> <td>Begin</td> <td><span>AGAIN</span></td>';
text.replace(/<span>([\s\S]*?)<\/span>/gi, '$1');

-> "<td>Hello</td> <td>WORLD</td> <td>Begin</td> <td>AGAIN</td>"