2010-02-13 6 views
1

J'ai un ensemble de requêtes regexp pour faire récursivement parcourir la chaîne dans l'ordre.javascript regex plusieurs requêtes

Y at-il un moyen que je peux tout faire avec 1 appel comme (ne fonctionne pas)?

str.replace(/query1|query2|query3|query4|...|[0-9]+|[^]/, 
      "reslt1|reslt2|reslt3|reslt4|...|procNumb|procChar"); 

Il suffit de travailler dans Firefox. En ce moment je suis coincé avec:

str.replace(... ,function(a,b,c){if (a=="query1") return "reslt1"; ..............}); 

Merci!

Éditer: Désolé si cela prête à confusion. Objectif:

Avant: "query1query3x123query2" Après: "reslt1reslt3procChar (x) procNumb (123) reslt2"

La chose principale est que je dois-je traiter la chaîne 1 fragment à la fois récursive, donc je pense Je dois utiliser une super-requête comme celle-ci pour correspondre à tout, ou ne pas utiliser d'expressions rationnelles du tout. Je me demande simplement s'il existe un moyen de jumeler automatiquement les résultats aux requêtes lorsque vous utilisez beaucoup de tuyaux. Je ne suis pas si familier avec javascript regex mais je n'ai malheureusement rien trouvé sur mdc.

+0

Ce que vous essayez de faire n'est pas clair. Pouvez-vous inclure des exemples «avant» et «après» (simplifiés, idéalement)? –

+0

Essayez-vous de combiner plusieurs appels 'str.replace' en un seul? Je ne pense pas que ce soit possible. Je voulais juste souligner que vous n'avez pas échappé '^' dans votre dernière regex,^signifie la négation dans une classe de caractères. Cela devrait être '[\ ^]'. – Amarghosh

+0

[^] correspond à un seul caractère de n'importe quoi. – user202987

Répondre

1

Si vous essayez de faire correspondre une de plusieurs sous-chaînes alternatives et fournir un résultat différent pour chaque match, vous allez devoir utiliser une fonction (comme vous semblez le faire). Par exemple:

var str = "ABCDE"; 

str = str.replace(/A|B|C|D/g, function(match) { 
    var rv; 
    switch (match) 
    { 
     case 'A': 
      rv = '1'; 
      break; 
     case 'B': 
      rv = '2'; 
      break; 
     case 'C': 
      rv = '3'; 
      break; 
     case 'D': 
      rv = '4'; 
      break; 
    } 
    return rv; 
}); 
alert(str); // Alerts 1234E 

(Bien sûr, cet exemple particulier serait mieux fait comme une recherche de tableau.)

Si vous êtes un maniaque de la brièveté verticale (je ne suis pas, mais certains sont), vous pouvez utiliser premiers retours:

str = str.replace(/A|B|C|D/g, function(match) { 
    switch (match) 
    { 
     case 'A': return '1'; 
     case 'B': return '2'; 
     case 'C': return '3'; 
     case 'D': return '4'; 
    } 
}); 
alert(str); // Alerts 1234E 

Modifier juste pour être clair, au sujet de mon commentaire « de recherche de tableau » ci-dessus: Si les remplacements sont vraiment juste une recherche statique, vous pouvez le faire:

var str, replacements, key, rex; 

// Potentially one-time prep, if you're re-using this lookup 
replacements = { 
    "A": "1", 
    "B": "2", 
    "C": "3", 
    "D": "4" 
}; 
rex = []; 
for (key in replacements) 
{ 
    rex.push(key); 
} 
rex = new RegExp(rex.join('|'), "g"); 

// The bit you reuse 
str = "ABCDE"; 
str = str.replace(rex, function(match) { 
    return replacements[match]; 
}); 
alert(str); // Alerts 1234E 

... puisque les objets JavaScript sont des tableaux associatifs.

+0

En ce qui concerne «Si vous êtes un démon de la concision verticale» - vous ne pouvez pas sérieusement dire que le premier exemple est plus lisible que le second, n'est-ce pas? –

+0

Je méprise tous les espaces, je suppose que je ferais ça alors (le second style: P), je rêvais juste d'une façon plus concise de l'écrire. Le formatage dans la chaîne de remplacement ... est logique. – user202987

+0

@Max: Je le trouve * comme * lisible, au moins; pas moins, pas plus. Des exemples triviaux comme ceux-ci forment une mauvaise base pour les débats sur la lisibilité. :-) Vous ne le feriez pas de toute façon, du moins pas en JavaScript; vous utiliseriez une recherche d'objet (tableau associatif). Mais pour tout ce qui est un peu plus complexe, je le ferais absolument la première fois. Une des directives habituelles de maintenabilité est d'avoir un seul retour d'une fonction. Ce n'est pas une ligne directrice que je suis toujours, mais en général, oui. Il facilite le débogage, rend la fonction moins fragile lors de l'amélioration, etc. –

0

Pourquoi les vous exécutez tout simplement pas un par un dans une boucle comme ceci:

for (var i = 0; i < regexes.length; i++) { 
    str = str.replace(regexes.regex, regexes.result); 
} 

Il est facile de comprendre, plus ou moins facile à entretenir, et probablement plus rapide d'une énorme requête. Ces alternatives dans regex viennent à un prix énorme.

0

En supposant que vous voulez remplacer query1 avec reslt1, query2 avec reslt2, et ainsi de suite, je ne pense pas que cela peut être fait en utilisant une seule regex. Cependant, il est assez en utilisant simplement un tableau NX2 (ou un objet, mais la définition de ce serait plus bavard):

var repl_table = [[/query1/g, 'reslt1'], 
        [/query2/g, 'reslt2'], 
        [/query3/g, 'reslt3'], 
        [/query4/g, 'reslt4'], 
        [/([0-9]+)/g, 'procNumb($1)'], 
        [/([^])/g, 'procChar($1)']] 

function repl(s, table) { 
    for (var i=0; i<table.length; i++) { 
    s = s.replace(table[i][0], table[i][1]); 
    } 
    return s; 
} 

// Then call: 
result = repl(source, repl_table);