JavaScript, RegExp - replace with evaluated expression involving tagged expressions?
RegExp can replace matched patterns with replacements involving what is known as Tagged Expressions
Example:
var s = "... some string with full things...";
s = s.replace(/(some|full)/gi, "\"aw$1\");
which will result in
'... "awsome" string with "awfull" things...'
And life are cool, because some and full are matched, and $1 in the replaced string reflects the matched Tagged开发者_如何学Python Expression in the braces, in this case - exactly only some or full.
Now, that we got the idea - I'm looking for an idea to do the following:
String before:
"{timeOfEffect: 3*24*60*60 }"
String after
"{timeOfEffect: 259200}"
The values are represented like that because they are edited by humans to graspable terms like (60 sec * 60 min * 24 hours)*3 => 3 days (don't ask. Client's request), but read in computer terms like 259200 in seconds, and could contain many occuring of that pattern.
I was thinking to try to create a replacement expression that multiplies $1 and $2, or even pass $1 and $2 to a function, or pass $1 * $2 to an evaluation context, but I have to create a function for it and do it manually.
The closest I got is
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));
That sucks a little because exec
returns only the first match.
After handling it in the replace statement - next search starts again from the start of the string - which is a string of 60K length...
A good solution will be one of the following: a) perform the match starting from an index (without creating a new substring for that) b) provide a replace expression that allows evaluation
The alternative approach will be to tokenize the string, and process it in bits - which is a total alternative to the RegExp
that will take a lot of code and effort, in which case I'll just live with the performance penalty or give a better fight on a better alternative for this requirement...
Help anybody?
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)
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()
is safe to use because we have ensured the string only contains 0-9
, ,
\n
, \t
, /
, *
, -
and +
. I was hoping there may be something like Math.parse()
, but there isn't.
If you need more complex math that requires parenthesis, simply add escaped (
and )
to the regex character range.
精彩评论