Get backreferences values and modificate these values

Posted by roasted on Stack Overflow See other posts from Stack Overflow or by roasted
Published on 2012-10-20T09:48:54Z Indexed on 2012/10/20 11:01 UTC
Read the original article Hit count: 148

Filed under:
|
|

Could you please explain why im not able to get values of backreferences from a matched regex result and apply it some modification before effective replacement?

The expected result is replacing for example string ".coord('X','Y')" by "X * Y". But if X > to some value, divide this value by 2 and then use this new value in replacement.

Here the code im currently testing:

See /*>>1<<*/ & /*>>2<<*/ & /*>>3<<*/, this is where im stuck!

I would like to be able to apply modification on backrefrences before replacement depending of backreferences values.

Difference between /*>>2<<*/ & /*>>3<<*/ is just the self call anonymous function param

The method /*>>2<<*/ is the expected working solution as i can understand it. But strangely, the replacement is not working correctly, replacing by alias $1 * $2 and not by value...?

You can test the jsfiddle

//string to test
".coord('125','255')"

//array of regex pattern and replacement //just one for the example
//for this example, pattern matching alphanumerics is not necessary (only decimal in coord) but keep it as it
var regexes = [ //FORMAT is array of [PATTERN,REPLACEMENT]
    /*.coord("X","Y")*/ [/\.coord\(['"]([\w]+)['"],['"]?([\w:\.\\]+)['"]?\)/g, '$1 * $2']
                  ];
function testReg(inputText, $output) {
    //using regex
    for (var i = 0; i < regexes.length; i++) {
        /*==>**1**/ //this one works as usual but dont let me get backreferences values
         $output.val(inputText.replace(regexes[i][0], regexes[i][2]));

         /*==>**2**/ //this one should works as i understand it
         $output.val(inputText.replace(regexes[i][0], function(match, $1, $2, $3, $4) { 
            $1 = checkReplace(match, $1, $2, $3, $4);
            //here want using $1 modified value in replacement
            return regexes[i][3]; 
        }));

         /*==>**3**/ //this one is just a test by self call anonymous function
         $output.val(inputText.replace(regexes[i][0], function(match, $1, $2, $3, $4) {
            $1 = checkReplace(match, $1, $2, $3, $4);
            //here want using $1 modified value in replacement
            return regexes[i][4];
        }()));

        inputText = $output.val();
    }
}

function checkReplace(match, $1, $2, $3, $4) {
    console.log(match + ':::' + $1 + ':::' + $2 + ':::' + $3 + ':::' + $4);
    //HERE i should be able if lets say $1 > 200 divide it by 2
    //then returning $1 value
    if($1 > 200) $1 = parseInt($1 / 2);
    return $1; 
}?

Sure I'm missing something, but cannot get it!

Thanks for your help, regards.

EDIT WORKING METHOD: Finally get it, as mentionned by Eric:

The key thing is that the function returns the literal text to substitute, not a string which is parsed for backreferences.??

JSFIDDLE

So complete working code: (please note as pattern replacement will change for each matched pattern and optimisation of speed code is not an issue here, i will keep it like that)

 $('#btn').click(function() {
    testReg($('#input').val(), $('#output'));
});

//array of regex pattern and replacement //just one for the example
var regexes = [ //FORMAT is array of [PATTERN,REPLACEMENT] /*.coord("X","Y")*/ 
    [/\.coord\(['"]([\w]+)['"],['"]?([\w:\.\\]+)['"]?\)/g, '$1 * $2']
                     ];

function testReg(inputText, $output) {
    //using regex
    for (var i = 0; i < regexes.length; i++) {
        $output.val(inputText.replace(regexes[i][0], function(match, $1, $2, $3, $4) {
            var checkedValues = checkReplace(match, $1, $2, $3, $4);
            $1 = checkedValues[0];
            $2 = checkedValues[1];
            regexes[i][1] = regexes[i][1].replace('$1', $1).replace('$2', $2);
            return  regexes[i][1];
        }));
        inputText = $output.val();
    }
}

function checkReplace(match, $1, $2, $3, $4) {
    console.log(match + ':::' + $1 + ':::' + $2 + ':::' + $3 + ':::' + $4);
    if ($1 > 200) $1 = parseInt($1 / 2);
    if ($2 > 200) $2 = parseInt($2 / 2);
    return [$1,$2];
}?

© Stack Overflow or respective owner

Related posts about JavaScript

Related posts about jQuery