正则表达式可以使用所谓的标记表达式替换匹配的模式。
例如:
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
的替代方案,但需要大量的代码和努力,如果这样的话,我只能接受性能损失或者寻找更好的替代方案来满足需求...
有人可以帮忙吗?
var r = new RegExp("([0-9\\.]+)([\\*+-\\/].)([0-9\\*+-\\/]+)([0-9])","g");
r = function(m,m1,m2,m3,m4){
try{
return ":" + eval(m1+m2+m3+m4)
}catch(ex){
return ":\"@@EVAL_ERROR:" + m1+m2+m3+m4 + "\""
}
}
}
s = s.replace(x,r)
输出显然会被检查是否包含 "@@EVAL_ERROR" 并发送邮件报告配置错误...谢谢 :) - Radagast the Brown