JavaScript, RegExp - replace with expression with expression expressions with tags?

RegExp can replace matched templates with a replacement using so-called tagged expressions

Example:

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

leading to

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

And life is cool, because some and full are matched, and $ 1 in the replaced line reflects the agreed Tagged Expression in curly brackets, in this case - just some or full .

Now we have an idea - I'm looking for an idea to do the following:

Line before:

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

Line after

 "{timeOfEffect: 259200}" 

The values โ€‹โ€‹are presented in this way because they are edited by people to understandable terms, such as (60 s * 60 min * 24 hours) * 3 => 3 days (do not ask, customer request), but read in computer terms like 259200 in seconds, and may contain many incidents of this pattern.

I was thinking of trying to create a replacement expression that multiplies $ 1 and $ 2, or even passes $ 1 and $ 2 to a function, or passes $ 1 * $ 2 to the evaluation context, but I need to create a function for it and do it manually.

The closest I got

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

This sucks a bit because exec returns only the first match . After processing it in the replace statement - the next search starts at the beginning of the line - this is a line with a length of 60K ...

A good solution would be one of the following: a) execute the match starting from the index (without creating a new substring for this) b) provide an expression for substitution that allows you to evaluate

An alternative approach would be to tokenize the string and process it in bits, which is a complete RegExp alternative that will require a lot of code and effort, in which case I will just live with a penalty performance or give a better fight on the best alternative for this requirement ...

Help someone?

+4
source share
2 answers
 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) 
+6
source
 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, as we have guaranteed that the string contains only 0-9 , , \n , \t , / , * , - and + . I was hoping there might be something like Math.parse() , but that is not.

If you need more complex maths requiring brackets, just add escaped ( ) to the regex character range.

+4
source

Source: https://habr.com/ru/post/1342265/


All Articles