4 votes

JavaScript, RegExp - remplacer par une expression évaluée impliquant des expressions balisées ?

RegExp peut remplacer les motifs appariés par des remplacements impliquant ce qui est connu sous le nom de Tagged Expressions

Ejemplo:

var s = "... some string with full things...";
s = s.replace(/(some|full)/gi, "\"aw$1\");

qui se traduira par

'... "awsome" string with "awfull" things...'

Et la vie est cool, parce que certains y complet sont appariés, et $1 dans la chaîne remplacée reflète la chaîne appariée. Tagged Expression dans les accolades, dans ce cas - exactement seulement certains o complet .

Maintenant que nous avons compris l'idée - Je cherche une idée pour faire ce qui suit :

Chaîne avant :

"{timeOfEffect: 3*24*60*60 }"

Chaîne après

"{timeOfEffect: 259200}"

Les valeurs sont représentées de cette manière parce qu'elles sont éditées par les humains en termes compréhensibles comme (60 sec * 60 min * 24 heures)*3 => 3 jours (ne demandez pas. Demande du client), mais lues en termes informatiques comme 259200 en secondes, et peuvent contenir de nombreuses occurrences de ce modèle.

Je pensais essayer de créer une expression de remplacement qui multiplie $1 et $2, ou même passer $1 et $2 à une fonction, ou passer $1 * $2 à un contexte d'évaluation, mais je dois créer une fonction pour cela et le faire manuellement.

Le plus proche que j'ai obtenu est

var x = /([0-9]*)\s\*\s([0-9]*)/g
  , r = function(m){
           return m[1] * m[2];
        }
while (m = x.exec(s))
  s = s.replace( x, r(m));

C'est un peu dommage parce que exec retours seulement le premier match . Après l'avoir traité dans l'instruction replace, la recherche suivante recommence au début de la chaîne - qui est une chaîne de 60K de long...

Une bonne solution sera l'une des suivantes : a) effectuer la correspondance à partir d'un index (sans créer de nouvelle sous-chaîne pour cela) b) fournir une expression de remplacement qui permet l'évaluation

L'approche alternative consistera à symboliser la chaîne de caractères et à la traiter en bits, ce qui constitue une alternative totale à l'option RegExp Cela nécessitera beaucoup de code et d'efforts, auquel cas je m'accommoderai de la pénalité de performance ou je me battrai pour une meilleure alternative pour cette exigence...

Quelqu'un a besoin d'aide ?

7voto

Igor Points 723
var s = "timeOfEffect: 3*24*60*60 var: 6*8 ";
var r = new RegExp("([0-9*+-/]{0,}[0-9])","g");
s = s.replace(r,function(match){ return eval(match); });
alert(s)

5voto

alex Points 186293
var str = '{timeOfEffect: 3*24*60*60}, {timeOfEffect: 1+7}, {timeOfEffect: 20-3}, {timeOfEffect: 3 / 0}';

var result = str.replace(/\s([\d\/\*\-\+\s]+?)\}/g, function(all, match) {
    return eval(match) + '}';
});

document.body.innerHTML = result;
// {timeOfEffect:259200}, {timeOfEffect:8}, {timeOfEffect:17}, {timeOfEffect:Infinity}

jsFiddle .

eval() peut être utilisée en toute sécurité, car nous nous sommes assurés que la chaîne ne contient que des 0-9 , , \n , \t , / , * , - y + . I était espérant il peut y avoir quelque chose comme Math.parse() mais ce n'est pas le cas.

Si vous avez besoin d'un calcul plus complexe nécessitant des parenthèses, il vous suffit d'ajouter une échappée. ( y ) à la plage de caractères de l'expression rationnelle.

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