2009-07-16 8 views
1

J'ai essayé d'utiliser une simple opération jQuery pour faire correspondre dynamiquement et stocker toutes les balises d'ancrage et leurs textes sur la page. Mais j'ai trouvé un comportement étrange. Lorsque vous utilisez match() ou exec(), si vous désignez l'aiguille comme un objet RegExp distinct ou une variable de modèle, votre requête ne correspond qu'à une seule instance parmi des dizaines dans la chaîne haystack.Javascript Match et RegExp problème - Comportement étrange

Et si vous désignez le modèle comme celui-ci

match(/needle/gi) 

il correspond à tous les cas de l'aiguille.

Voici mon code.

Vous pouvez même lancer Firebug et essayer ce code ici même sur cette page.

var a = {'text':'','parent':[]}; 

$("a").each(function(i,n) { 

    var module = $.trim($(n).text()); 
    a.text += module.toLowerCase() + ',' + i + ','; 

    a.parent.push($(n).parent().parent()); 

}); 

var stringLowerCase = 'b'; 

var regex = new RegExp(stringLowerCase, "gi"); 
//console.log(a.text); 
console.log("regex 1: ", regex.exec(a.text)); 

var regex2 = "/" + stringLowerCase + "/"; 
console.log("regex 2: ", a.text.match(regex2)); 

console.log("regex 3: ", a.text.match(/b/gi)); 

Pour moi, il retourne:

regex 1: ["b"] 
regex 2: null 
regex 3: ["b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b", "b"] 

Quelqu'un peut-il expliquer la racine de ce comportement? : J'ai oublié de mentionner que pour regex1, il ne fait aucune différence si vous ajoutez les drapeaux "gi" pour la correspondance globale et insensible à la casse. Il retourne toujours un seul match.

EDIT2: J'ai rencontré mon propre problème. Je ne sais toujours pas pourquoi une regex1 correspond à une seule instance, mais j'ai réussi à faire correspondre toutes les instances en utilisant match() et regex1.

Donc, cela correspond à tous et dynamiquement!

var regex = new RegExp(stringLowerCase, "gi"); 
console.log("regex 2: ", a.text.match(regex)); 
+0

Quel est le contenu de a.text –

+0

un est juste un objet avec deux éléments. Je l'ai défini en haut du code. Son contexte est probablement l'objet document. – picardo

Répondre

4

Ce comportement n'est pas inhabituel. Dans regex 1, vous en vérifiez seulement une instance où, dans regex 3, vous lui avez demandé de renvoyer toutes les instances de l'élément en utilisant l'argument/gi.

Dans Regex 2, vous supposez que "/ b /" ===/b/quand ce n'est pas le cas. "/ b /"! ==/b /. "/ b /" est une chaîne qui cherche donc si vous avez "/ b /" dans la chaîne alors elle retournera alors que/b/signifie qu'elle doit chercher entre les barres obliques pour que vous puissiez avoir "abc" retour "b"

J'espère que cela aide.

EDIT:

En regardant dans un peu plus, les méthodes exec renvoie le premier match qu'il trouve plutôt que tous les matches qu'il trouve.

EDIT:

var myRe = /ab*/g; 
var str = "abbcdefabh"; 
var myArray; 
while ((myArray = myRe.exec(str)) != null) 
{ 
    var msg = "Found " + myArray[0] + ". "; 
    msg += "Next match starts at " + myRe.lastIndex; 
    console.log(msg); 
} 

Avoir un regard à nouveau, il ne retourne définitivement la première instance qu'il trouve. Si vous l'avez bouclé, vous reviendrez plus.

Pourquoi cela? Je n'ai aucune idée ... mon Kung Fu JavaScript n'est clairement pas assez fort pour répondre à cette partie

+0

J'aurais dû le préciser. Pour le regx1, cela ne fait pas de différence quand j'ai ajouté "gi" à la définition de l'objet RegExp. Essayez-le vous-même. – picardo

+0

Savez-vous pourquoi ça fait ça? J'ai ajouté le drapeau g dans la définition RegExp, donc il devrait faire une correspondance globale, non? – picardo

0

regex2 est une chaîne, pas un RegExp, j'ai eu du mal aussi utiliser ce type de syntaxe, quoique je ne suis pas vraiment sûr du comportement. Editer: Remebered: pour regex2, JS cherche "/ b /" comme une aiguille, pas "b".

+0

Mais qu'en est-il de regex1? Cela aurait dû marcher. Comment avez-vous fini par résoudre vos problèmes? – picardo

2

La raison pour laquelle regex 2 renvoie null est que vous passez "/ b /" comme paramètre de modèle, tandis que "b" est en fait la seule chose qui fait partie du modèle. Les barres obliques sont des raccourcis pour regex, tout comme [] pour array. Donc si vous deviez remplacer cela par new regex ("b"), vous obtiendriez une correspondance, mais une seule, puisque vous omettez les drapeaux "global + ignorecase" dans cet exemple. Pour obtenir les mêmes résultats pour # 2 et # 3, modifier en conséquence:

var regex2 = stringLowerCase; 
console.log("regex 2: ", a.text.match(regex2, "gi")); 
console.log("regex 3: ", a.text.match(/b/gi));