Javascript正则表达式 - 匹配字符串模式,除非字符串在特定标记内

时间:2008-11-26 19:57:55

标签: javascript regex

我正在尝试替换??? some.text.and.dots ???的所有出现?在html页面中添加链接。我已经构建了这个正则表达式:

\?\?\?([A-Z0-9] *)\?\?\?

但是,我想排除链接中的任何结果:“< a ...> ... MY PATTERN ...< / a>”,我有点卡住了怎么做,我现在所有的尝试都失败了。

2 个答案:

答案 0 :(得分:9)

你正在研究什么样的“HTML”并不是很清楚。如果它是HTML 代码,可能来自Ajax请求,那么你可以使用正则表达式;匹配链接模式,然后找出回调中的操作:

var html = document.body.innerHTML;
html = html.replace(/(<a\s.*?>.*?<\/a>)|(\?\?\?([a-z0-9.]*)\?\?\?)/g, 
    function ( a, b, c, d ) {
       return ( a[0] == '<' ) ? a : '<a href="#">' + d + '</a>'; 
    });
context.innerHTML = html;

方便地,replace() can take a callback function作为替代生成器,而不是简单的字符串。

但是,如果您正在处理实时DOM树,则可能需要尊重节点上的事件,而不是简单地重置innerHTML。你需要更原始的方法:

// returns all childnodes of type text that do not have A as parent
function walker ( node ) {
  var nodes = [];
  for (var c, i = 0; c = node.childNodes[i]; i++) {
    if ( c.nodeType === 1 && c.tagName !== 'A' ) {
      nodes = nodes.concat( arguments.callee( c ) );
    }
    else if ( c.nodeType === 3 ) { 
      nodes.push( c );
    }
  }
  return nodes;
}

var textNodes = walker( document.body );
for (var i = 0; i < textNodes.length; i++) {
  // create an array of strings separating the pattern
  var m = textNodes[i].nodeValue.split( /(\?\?\?([a-z0-9.]*)\?\?\?)/ );
  if ( m.length > 1 ) {
    for (var j=0; j<m.length; j++) {
      var t, parent = textNodes[i].parentNode;
      // create a link for any occurence of the pattern
      if ( /^\?\?\?([a-z0-9.]*)\?\?\?$/.test( m[j] ) ) {
        var a = document.createElement( 'a' );
        a.href = "#";
        a.innerHTML = RegExp.$1;  // m[j] if you don't want to crop the ???'s
        parent.insertBefore( a, textNodes[i] );
        t = document.createTextNode( ' ' ); // whitespace padding
      }
      else {
        t = document.createTextNode( m[j] );
      }
      parent.insertBefore( t, textNodes[i] );
    }
    // remove original text node
    parent.removeChild( textNodes[i] );
  }
}

此方法仅触及文本节点,然后仅触及与模式匹配的文本节点。

答案 1 :(得分:0)

JavaScript本身并不支持后视。为了做到这一点,你需要运行.match(),然后对于你的每个匹配,你需要在你的标签上做匹配(例如/<a\s+.*?>/ being在比赛开始前,然后在比赛结束后&lt; / a&gt;。

祝你好运!!