Javascript Regexp loop todos los partidos


Estoy tratando de hacer algo similar con el editor de texto enriquecido de stack overflow. Dado este texto:

[Text Example][1]

[1][http://www.example.com]

Quiero hacer un bucle de cada [string][int] que se encuentra, lo que hago de esta manera:

var Text = "[Text Example][1]\n[1][http: //www.example.com]";
// Find resource links
var arrMatch = null;
var rePattern = new RegExp(
  "\\[(.+?)\\]\\[([0-9]+)\\]",
  "gi"
);
while (arrMatch = rePattern.exec(Text)) {
  console.log("ok");
}

Esto funciona muy bien, alerta 'ok' para cada [string][int]. Lo que tengo que hacer, sin embargo, es para cada partido encontrado, reemplazar la coincidencia inicial con componentes de la segunda coincidencia.

Así que en el bucle represent 2 representaría la parte int originalmente emparejada, y ejecutaría esta expresión regular (pseduo)

while (arrMatch = rePattern.exec(Text)) {
    var FindIndex = $2; // This would be 1 in our example
    new RegExp("\\[" + FindIndex + "\\]\\[(.+?)\\]", "g")

    // Replace original match now with hyperlink
}

Esto coincidiría

[1][http://www.example.com]

El resultado final para el primer ejemplo sería:

<a href="http://www.example.com" rel="nofollow">Text Example</a>

Editar

He llegado hasta aquí ahora:

var Text = "[Text Example][1]\n[1][http: //www.example.com]";
// Find resource links
reg = new RegExp(
  "\\[(.+?)\\]\\[([0-9]+)\\]",
  "gi");
var result;
while ((result = reg.exec(Text)) !== null) {
  var LinkText = result[1];
  var Match = result[0];
  Text = Text.replace(new RegExp(Match, "g"), '<a href="#">" + LinkText + "</a>');
}
console.log(Text);
Author: Ruslan López, 2011-04-29

6 answers

Estoy de acuerdo con Jason en que sería más rápido/seguro usar una biblioteca de Markdown existente, pero estás buscando Cadena.prototipo.reemplazar (también, utilizar literales RegExp!):

var Text = "[Text Example][1]\n[1][http: //www.example.com]";
var rePattern = /\[(.+?)\]\[([0-9]+)\]/gi;

console.log(Text.replace(rePattern, function(match, text, urlId) {
  // return an appropriately-formatted link
  return `<a href="${urlId}">${text}</a>`;
}));
 36
Author: s4y,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-16 02:41:13

Me las arreglé para hacerlo al final con esto:

var Text = "[Text Example][1]\n[1][http: //www.example.com]";
// Find resource links
reg = new RegExp(
  "\\[(.+?)\\]\\[([0-9]+)\\]",
  "gi");
var result;
while (result = reg.exec(Text)) {
  var LinkText = result[1];
  var Match = result[0];
  var LinkID = result[2];
  var FoundURL = new RegExp("\\[" + LinkID + "\\]\\[(.+?)\\]", "g").exec(Text);
  Text = Text.replace(Match, '<a href="' + FoundURL[1] + '" rel="nofollow">' + LinkText + '</a>');
}
console.log(Text);
 32
Author: Tom Gullen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-16 01:06:13

Aquí estamos usando el método exec, ayuda a obtener todas las coincidencias (con help while loop) y obtener la posición de la cadena coincidente.

    var input = "A 3 numbers in 333";
    var regExp = /\b(\d+)\b/g, match;
    while (match = regExp.exec(input))
      console.log("Found", match[1], "at", match.index);
    // → Found 3 at 2 //   Found 333 at 15 
 3
Author: Vasyl Gutnyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-27 21:58:24

Este formato se basa en Markdown. Hay varios puertos JavaScript disponibles. Si no quieres toda la sintaxis, entonces te recomiendo robar las partes relacionadas con los enlaces.

 1
Author: Jason McCreary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-29 17:49:11

Aquí hay un pequeño ejemplo que espero que pueda encontrar útil. \number se usa en expresiones regulares para referir un número de coincidencia de grupo y $number se usa en la función reemplazar para referir resultados de grupo para que pueda imponer que los números sean los mismos con algo así si su texto es

[Text Example][1]\n[1][http://www.example.com]

Coincidirá y si es

[Text Example][1]\n[2][http://www.example.com]

No lo hará

var re = /\[(.+?)\]\[([0-9]+)\s*.*\s*\[(\2)\]\[(.+?)\]/gi;
var str = '[Text Example][1]\n[1][http://www.example.com]';
var subst = '<a href="$4">$1</a>';

var result = str.replace(re, subst);
console.log(result);
 0
Author: Ruslan López,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-16 01:34:52

Otra forma de iterar sobre todas las coincidencias sin depender de sutilezas exec y match, es usar la función string replace usando la expresión regular como primer parámetro y una función como segundo parámetro. Cuando se usa así, el argumento de la función recibe la coincidencia completa como el primer parámetro, las coincidencias agrupadas como los siguientes parámetros y el índice como el último:

var text = "[Text Example][1]\n[1][http: //www.example.com]";
// Find resource links
var arrMatch = null;
var rePattern = new RegExp("\\[(.+?)\\]\\[([0-9]+)\\]", "gi");
text.replace(rePattern, function(match, g1, g2, index){
    // Do whatever
})

Incluso puede iterar sobre todos los grupos de cada coincidencia utilizando la variable JS global arguments, excluyendo la primera y la última aquel.

 0
Author: Mario Vázquez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-05 17:39:05