Javascript Regexp - соответствует шаблону строки, кроме случаев, когда строка находится внутри указанного тега

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

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

Однако я хотел бы исключить любой результат, который находится внутри ссылки: «<a ...> ... МОЙ ШАБЛОН ... </a>», и я немного не знаю, как это сделать, все мои попытки пока не увенчались успехом.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
6 147
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

JavaScript по своей сути не поддерживает ретроспективный анализ. Для этого вам нужно будет запустить .match (), а затем для каждого из ваших совпадений вам нужно будет выполнять совпадения с вашими тегами (например, /<a\s+.*?>/ находится непосредственно перед ваш матч, а затем </a> после вашего матча).

Удачи!!

+1 «Имитация ретроспективного просмотра в Javascript»: blog.stevenlevithan.com/archives/mimic-lookbehind-javascript

enobrev 26.11.2008 23:14
Ответ принят как подходящий

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

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

VonC 27.11.2008 10:44

Ну, я пытался использовать функцию ретроспективного выражения регулярного выражения, не зная, что она не поддерживается javascript. Однако ваша функция отлично подходит для моих целей. Спасибо!

Pouletfou 27.11.2008 19:34

Другие вопросы по теме