JavaScript、RegExp - 替换为涉及标记表达式的评估表达式?
RegExp 可以用涉及所谓的标记表达式的替换来替换匹配的模式
示例:
var s = "... some string with full things...";
s = s.replace(/(some|full)/gi, "\"aw$1\");
这将导致
'... "awsome" string with "awfull" things...'
生活很酷,因为 some 和 full被匹配,替换字符串中的 $1 反映了大括号中匹配的标记表达式,在本例中 - 恰好只有 some 或 full。
现在,我们有了这个想法—— 我正在寻找执行以下操作的想法:
String before:
"{timeOfEffect: 3*24*60*60 }"
String after
"{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
的完全替代方案,需要大量的代码和工作,在这种情况下,我将忍受性能损失,或者更好地争取更好的替代方案来满足此要求......
帮助任何人吗?
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 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
jsFiddle。
eval()
可以安全使用,因为我们确保字符串仅包含0-9
、、
\n
、\t
、/
、*
、-
和+
。 我希望希望可能有类似的东西Math.parse()
,但没有。如果您需要需要括号的更复杂的数学,只需将转义
(
和)
添加到正则表达式字符范围即可。jsFiddle.
eval()
is safe to use because we have ensured the string only contains0-9
,,
\n
,\t
,/
,*
,-
and+
. I was hoping there may be something likeMath.parse()
, but there isn't.If you need more complex math that requires parenthesis, simply add escaped
(
and)
to the regex character range.