161 votes

Comment faire correspondre plusieurs occurrences avec une expression rationnelle en JavaScript similaire à PHP preg_match_all ()?

Je suis en train d'analyser url-encodé les chaînes sont constituées de paires valeur / clé séparés par & ou &.

Les éléments suivants ne correspondent à la première occurrence, briser les clés et les valeurs en différents éléments:

var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/)

Les résultats de la chaîne '1111342=Adam%20Franco&348572=Bob%20Jones" serait:

['1111342', 'Adam%20Franco']

À l'aide de l'indicateur global, 'g', correspond à tous les événements, mais uniquement retourner le bien adaptée sous-chaînes, pas la séparation de clés et de valeurs:

var result = mystring.match(/(?:&|&)?([^=]+)=([^&]+)/g)

Les résultats de la chaîne '1111342=Adam%20Franco&348572=Bob%20Jones" serait:

['1111342=Adam%20Franco', '&348572=Bob%20Jones']

Alors que je pouvais diviser la chaîne sur & et séparer chaque paire clé/valeur individuellement, est-il possible à l'aide de JavaScript support des expressions régulières pour correspondre à de multiples occurrences de la séquence /(?:&|&)?([^=]+)=([^&]+)/ similaire à PHP preg_match_all() fonction?

Je vise une certaine façon à obtenir des résultats avec le sous-correspondances séparés comme:

[['1111342', '348572'], ['Adam%20Franco', 'Bob%20Jones']]

ou

[['1111342', 'Adam%20Franco'], ['348572', 'Bob%20Jones']]

165voto

Tomalak Points 150423

Je voudrais proposer une autre regex, à l'aide des sous-groupes pour capturer le nom et la valeur des paramètres individuellement:

function getUrlParams(url) {
  var re = /(?:\?|&(?:amp;)?)([^=&#]+)(?:=?([^&#]*))/g,
      match, params = {},
      decode = function (s) {return decodeURIComponent(s.replace(/\+/g, " "));};

  if (typeof url == "undefined") url = document.location.href;

  while (match = re.exec(url)) {
    params[decode(match[1])] = decode(match[2]);
  }
  return params;
}

var result = getUrlParams("http://maps.google.de/maps?f=q&source=s_q&hl=de&geocode=&q=Frankfurt+am+Main&sll=50.106047,8.679886&sspn=0.370369,0.833588&ie=UTF8&ll=50.116616,8.680573&spn=0.35972,0.833588&z=11&iwloc=addr");

result est un objet:

{
 f: "q"
 géocodage: ""
 hl: "de"
 c'est à dire: "UTF8"
 iwloc: "addr"
 ll: "50.116616,8.680573"
 q: "Francfort"
 sll: "50.106047,8.679886"
 source: "s_q"
 spn: "0.35972,0.833588"
 sspn: "0.370369,0.833588"
 z: "11"
}

La regex se décompose comme suit:

(?: # non-capture d'un groupe
 \?|& # "?" ou "&"
 (?:amp;)? # (autoriser "&", à tort codé en HTML Url)
) # fin de non-capture d'un groupe
( # groupe 1
 [^=]+ # n'importe quel caractère sauf "=", "&" ou "#"; au moins une fois
) # fin du groupe 1 - ce sera le nom du paramètre
(?: # non-capture d'un groupe
 =? # un "=", en option
 ( # groupe 2
 [^]* # n'importe quel caractère sauf "&" ou "#"; n'importe quel nombre de fois
 ) # fin du groupe 2 - ce sera la valeur du paramètre
) # fin de non-capture d'un groupe

67voto

meouw Points 21368

Vous devez utiliser le commutateur 'g' pour une recherche globale

 var result = mystring.match(/(&|&)?([^=]+)=([^&]+)/g)
 

40voto

Pour être complet, JavaScript est intégré à cette commande, à l'exception de ce qu'il s'appelle replace .

 var data = {};
var getKeyValue = function(a,b,c,d) { data[c] = d; };
mystring.replace(/(?:&|&)?([^=]+)=([^&]+)/g, getKeyValue);
 

terminé. a correspond au motif complet, b et sur sont des groupes de capture, avec b groupe 1, c groupe 2, etc. .

Ainsi, plutôt que d'écrire des fonctions d'analyse compliquées, rappelez-vous simplement que "matchAll" dans JavaScript est "replace" avec une fonction de gestionnaire de remplacement au lieu d'une chaîne de remplacement.

21voto

Aram Kocharyan Points 8530

Pour capturer des groupes, j'ai l'habitude d'utiliser preg_match_all en PHP et j'ai essayé de reproduire ses fonctionnalités ici:

 <script>

// Return all pattern matches with captured groups
RegExp.prototype.execAll = function(string) {
    var match = null;
    var matches = new Array();
    while (match = this.exec(string)) {
        var matchArray = [];
        for (i in match) {
            if (parseInt(i) == i) {
                matchArray.push(match[i]);
            }
        }
        matches.push(matchArray);
    }
    return matches;
}

// Example
var someTxt = 'abc123 def456 ghi890';
var results = /[a-z]+(\d+)/g.execAll(someTxt);

// Output
[["abc123", "123"],
 ["def456", "456"],
 ["ghi890", "890"]]

</script>
 

14voto

Gumbo Points 279147

Définissez le modificateur g pour une correspondance globale:

 /…/g
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X