2009-11-21 3 views
0

Я преобразовал html в строку, я могу использовать замену в этой строке, чтобы обернуть текст ссылкой, и я могу поместить этот html обратно в идентификатор, из которого он пришел.Как искать/заменять текст с помощью обертки «href» в JavaScript?

Моя проблема заключается в том, что мой метод замены будет внутри существующих ссылок на странице. Это может создать вложенные ссылки, что является проблемой. Кто-нибудь знает, как предотвратить метод замещения от совпадения текста, который уже находится в ссылке?

я прямо сейчас:

keyword = "matching phrase"; 
keywordLink = "<a href='http://myurl.com'/>" + keyword + "</a>"; 
sasser = sasser.replace(keyword, keywordLink); 
sasDom.innerHTML = sasser; 

Я ищу, в псевдокоде:

... (keyword [if the next " < " sign is not followed by "/a>", regardless of how far away it is], keywordLink); 

ответ

2

Вы не можете делайте подобные вещи с помощью регулярного выражения. Работа над объектами документа, которые уже хорошо разбираются в структуре для вас.

Вот ключевой компоновщик, адаптированный из this question.

// Find text in descendents of an element, in reverse document order 
// pattern must be a regexp with global flag 
// 
function findTextExceptInLinks(element, pattern, callback) { 
    for (var childi= element.childNodes.length; childi-->0;) { 
     var child= element.childNodes[childi]; 
     if (child.nodeType===1) { 
      if (child.tagName.toLowerCase()!=='a') 
       findTextExceptInLinks(child, pattern, callback); 
     } else if (child.nodeType===3) { 
      var matches= []; 
      var match; 
      while (match= pattern.exec(child.data)) 
       matches.push(match); 
      for (var i= matches.length; i-->0;) 
       callback.call(window, child, matches[i]); 
     } 
    } 
} 

findTextExceptInLinks(document.body, /\bmatching phrase\b/g, function(node, match) { 
    node.splitText(match.index+match[0].length); 
    var a= document.createElement('a'); 
    a.href= 'http://www.example.com/myurl'; 
    a.appendChild(node.splitText(match.index)); 
    node.parentNode.insertBefore(a, node.nextSibling); 
}); 

ета повторно комментариев: Вот версия одного и того же с помощью обычного текстового соответствия, а не регулярное выражение:

function findPlainTextExceptInLinks(element, substring, callback) { 
    for (var childi= element.childNodes.length; childi-->0;) { 
     var child= element.childNodes[childi]; 
     if (child.nodeType===1) { 
      if (child.tagName.toLowerCase()!=='a') 
       findPlainTextExceptInLinks(child, substring, callback); 
     } else if (child.nodeType===3) { 
      var index= child.data.length; 
      while (true) { 
       index= child.data.lastIndexOf(substring, index); 
       if (index===-1) 
        break; 
       callback.call(window, child, index) 
      } 
     } 
    } 
} 

var substring= 'matching phrase'; 
findPlainTextExceptInLinks(document.body, substring, function(node, index) { 
    node.splitText(index+substring.length); 
    var a= document.createElement('a'); 
    a.href= 'http://www.example.com/myurl'; 
    a.appendChild(node.splitText(index)); 
    node.parentNode.insertBefore(a, node.nextSibling); 
}); 
+0

Бобинс - большое вам спасибо! Это решение является фантастическим, и я очень благодарен вам за то, что вы потратили время, чтобы опубликовать его. У меня сейчас есть относительно простая проблема ... Я не могу использовать переменную как соответствующую фразу. Вот что я пытаюсь: findTextExceptInLinks (document.body, "/ \ b" + variable + "\ b/g", function (node, match) { – Matrym

+0

findTextExceptInLinks (document.body, "/ \ b" + переменная + "\ b/g", функция (узел, совпадение) { – Matrym

+0

@google: попробуйте передать новый RegExp ('\\ b' + variable + '\\ b', 'g') ' –

1

Если вы не возражаете против использования JQuery, вы можете использовать его wrap() функцию, чтобы обернуть text или html в указанных тегах.

+0

ли эта работа для упаковки только часть текста внутри некоторых тегов, тоже? – Franz

+0

Думая об этом, это, вероятно, не помешает вам иметь вложенные теги ссылок или будет? – Franz

0

Я хотел бы сделать это в три этапа:

1) заменить <a [^>]+>matching phrase</a> с $1some_other_phrase</a>

2) заменить matching phrase с <a...>keyword</a>

3) заменить some_other_phrase с matching phrase

Смежные вопросы