JavaScript,RegExp - 替换为涉及标记表达式的计算表达式?

时间:2011-03-04 09:16:59

标签: javascript regex replace evaluate

RegExp可以替换匹配的模式,替换涉及所谓的标记表达式

示例:

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

将导致

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

生活很酷,因为一些完整匹配,并且替换字符串中的$ 1反映了大括号中匹配的标记表达式 ,在这种情况下 - 只有某些完整

现在,我们得到了这个想法 - 我正在寻找一个想法来做到以下几点:

之前的字符串:

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

之后的字符串
"{timeOfEffect: 259200}"

这些值是这样表示的,因为它们由人类编辑为可掌握的术语,如(60秒* 60分钟* 24小时)* 3 => 3天(不要问。客户的要求),但在几秒钟内阅读像259200这样的计算机术语,并且可能包含很多这种模式。

我正在考虑尝试创建一个替换表达式,它将$ 1和$ 2相乘,或者甚至将$ 1和$ 2传递给一个函数,或者将$ 1 * $ 2传递给一个评估上下文,但我必须为它创建一个函数并执行手动。

我最接近的是

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));

这很糟糕,因为exec只返回第一场比赛。 在替换语句中处理后 - 下一次搜索从字符串的开头再次开始 - 这是一个60K长的字符串......

一个好的解决方案将是以下之一: a)从索引开始执行匹配(不创建新的子字符串) b)提供允许评估的替换表达式

另一种方法是对字符串进行标记化,并以位为单位进行处理 - 这是RegExp的完全替代方案,需要大量的代码和工作,在这种情况下,我只会忍受性能损失或更好地争取更好的替代方案......

帮助任何人?

2 个答案:

答案 0 :(得分:7)

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)

答案 1 :(得分:5)

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()可以安全使用,因为我们确保字符串只包含0-9\n\t/*-+I was hoping可能有类似Math.parse()的内容,但没有。{/ p>

如果您需要更复杂的数学需要括号,只需将转义()添加到正则表达式字符范围。