Javascript Regexp - Соответствует строковому образцу за исключением случаев, когда строка находится внутри указанного тега - PullRequest
3 голосов
/ 26 ноября 2008

Я пытаюсь заменить все вхождения «some.text.and.dots» в HTML-страницу, чтобы добавить ссылку на него. Я построил это регулярное выражение, которое делает это:

\? \? \? ([А-z0-9.] *) \? \? \?

Однако я хотел бы исключить любой результат, который находится внутри ссылки: " ... МОЙ РИСУНОК ... ", и я немного застрял, как это сделать все мои попытки пока провалились.

Ответы [ 2 ]

9 голосов
/ 27 ноября 2008

Не совсем понятно, над каким «HTML» вы работаете. Если это HTML code , что-то из запроса 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() может использовать функцию обратного вызова в качестве генератора замены, а не простую строку.

Однако, если вы работаете с живым 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] );
  }
}

Этот метод касается только текстовых узлов, а затем только тех, которые соответствуют шаблону.

0 голосов
/ 26 ноября 2008

JavaScript по своей природе не поддерживает просмотр. Чтобы сделать это, вам нужно запустить .match (), а затем для каждого из ваших совпадений вам нужно будет сделать совпадения для ваших тегов (таких как // непосредственно перед ваш матч и затем после вашего матча).

Удачи !!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...