web-dev-qa-db-fra.com

Javascript Regexp boucle tous les résultats

J'essaie de faire quelque chose de similaire avec l'éditeur de texte riche de débordement de pile. Compte tenu de ce texte:

[Text Example][1]

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

Je veux boucler chaque [string][int] trouvé que je fais de cette façon:

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");
}

Cela fonctionne très bien, il alerte «ok» pour chaque [string][int]. Ce que je dois faire cependant, c'est pour chaque correspondance trouvée, remplacer la correspondance initiale par les composants de la seconde correspondance.

Donc, dans la boucle, $ 2 représenterait la partie int initialement appariée, et je lancerais cette expression rationnelle (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
}

Cela correspondrait

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

Le résultat final pour le premier exemple serait:

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

Modifier

Je suis allé aussi loin que cela maintenant:

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);

36
Tom Gullen

J'ai réussi à le faire à la fin avec ceci:

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);

33
Tom Gullen

Je suis d’accord avec Jason pour dire qu’il serait plus rapide et plus sûr d’utiliser une bibliothèque Markdown existante, mais vous recherchez String.prototype.replace (également, utilisez les littéraux 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
s4y

Ici, nous utilisons exec method, il est utile d’obtenir toutes les correspondances (avec l’aide en boucle) et la position de la chaîne correspondante.

    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
Vasyl Gutnyk

Ce format est basé sur Markdown . Il y a plusieurs ports JavaScript disponible. Si vous ne voulez pas la syntaxe complète, je vous recommande donc stealing les parties relatives aux liens.

1
Jason McCreary

Une autre façon de parcourir toutes les correspondances sans s'appuyer sur exec et sur les subtilités des correspondances consiste à utiliser la fonction de remplacement de chaîne en utilisant l'expression rationnelle comme premier paramètre et une fonction en tant que second. Lorsqu'il est utilisé comme ceci, l'argument de la fonction reçoit la correspondance entière en tant que premier paramètre, les regroupements correspondent en tant que paramètres suivants et l'index en tant que dernier:

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
})

Vous pouvez même parcourir tous les groupes de chaque correspondance à l'aide de la variable JS globale arguments, en excluant la première et la dernière.

0
Mario Vázquez

Voici un petit exemple. J'espère que vous trouverez utile. .\number est utilisé dans regex pour désigner un numéro de correspondance de groupe et $number est utilisé dans la fonction de remplacement pour faire référence aux résultats du groupe afin que vous puissiez imposer que les nombres soient identiques à quelque chose comme que si votre texte est 

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

il va correspondre et si c'est

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

ça ne va pas

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
Ruslan López