Tengo el caso en el que estoy recorriendo la matriz de URL (por ejemplo, [www.stackoverflow.com, www.ex.com] ) y haciendo coincidir esas URL una por una con la cadena dada durante el ciclo y reemplazando con etiqueta de anclaje para hacerlo se puede hacer clic
Puedo hacerlo usando el método JS replaceAll pero en caso de múltiples apariciones de la misma URL en una cadena dada, incluso coincide con la URL en la etiqueta.
Por ejemplo, si la cadena dada es "Check it out at www.stack.com/abc and bookmark the www.stack.com, www.overflow.com" y la matriz de URL dada es [www.stack.com/abc, www.stack.com]
Durante la primera iteración de reemplazo, será "Check it out at <a href="www.stack.com/abc">www.stack.com/abc</a> and bookmark the www.stack.com"
y luego ocurre el problema durante la segunda iteración, reemplazará la cadena incluso en la etiqueta. Quiero ignorar la etiqueta html durante el método replaceAll . Alguien me puede ayudar con esto ?
Intenté ignorar las etiquetas con la siguiente expresión regular, pero no funciona para el contenido entre las etiquetas de anclaje.
exString.replaceAll(new RegExp(url + "(?![^<>]*>)", "gi"), replaceText);Vamos a dividirnos y unirnos entonces
const div = document.getElementById("text"); let str = div.textContent; let arr = str.split(/ /) console.log(arr) const urls = ["www.stack.com/abc", "www.stack.com"]; arr.forEach((word,i) => { const punctuation = word.match(/(\W$)/) if (punctuation) word = word.slice(0,-1) const idx = urls.indexOf(word); if (idx !=-1) arr[i] = arr[i].replace(word,`<a href="${word}">${word}</a>`) }) console.log(arr) div.innerHTML = arr.join(" ") <div id="text">Check it out at www.stack.com/abc and bookmark the www.stack.com, www.overflow.com.</div>Aunque la solución proporcionada por mplungjan es inteligente y funciona bien, quería publicar una alternativa.
El algoritmo de la respuesta aceptada procesa la cadena de entrada en una matriz de palabras y luego procede a recorrer cada palabra en cada URL. Luego necesita ver si alguna palabra termina con un símbolo, y truncar si es así. Esto consumiría un poco, ya que uno puede imaginar 50 palabras X 5 URL posibles = 250 combinaciones y cálculo O (n ^ 2). Luego, imagine que podría haber 20 URL posibles y 20 textos de entrada, cada uno con más de 15 palabras. Y finalmente, mencionar que el algoritmo puede tener problemas con la distinción entre mayúsculas y minúsculas.
Esta solución usa mucho el pensamiento del enfoque de mplungjan, pero en cambio, solo reducirá rápidamente lo que realmente necesita procesar a través de RegEx, y luego volverá a repetir para aplicar lo que realmente coincidió. Además, RegEx corrige el posible problema de sensibilidad entre mayúsculas y minúsculas.
let str = 'Check it out at www.stack.com/abc and bookmark the www.stack.com, www.overflow.com.'; let urls = ["www.stack.com", "www.stack.com/abc", "www.not-here.com"]; let arReplace = []; // sort by longest URLs (prevents processing identical root domains on sub-domains) urls = urls.sort((a, b) =>{ if(b.length > a.length) return 1 return -1 }); // find URLs and apply replacement tokens urls.forEach((url) => { if(str.match(new RegExp('\\b' + url + '\\b', 'i'))){ arReplace.push(url); str = str.replace(new RegExp('\\b' + url + '\\b', 'gi'), '%ZZ' + (arReplace.length - 1) + 'ZZ%') } }); // replace tokens arReplace.forEach((url, n) =>{ str = str.replace(new RegExp('%ZZ' + n + 'ZZ%', 'g'), '<a href="' + url + '">' + url + '</a>') }); document.body.innerHTML = strEnlace de violín: https://jsfiddle.net/e05o9cra/