Nathan Friend
Nathan Friend

Reputation: 12814

Best way to get string representation of regex from regex literal

If I do this:

// note that \x1f is a control character
var regex = new RegExp("\x1f");

// prints "//"
console.log(regex.toString()); 

If I instead do this:

var regex = /\\x1f/;

// prints "/\\x1f/"
console.log(regex.toString());

I'd like to be able to get the first result (// - a string with a control character) from the second regular expression. Is there a simple way to do this? So far, I've only been able to do this with a disgusting eval hack:

var regexValue = /\\x1f/.toString();

let escapedLiteral = regexValue

    // turn double backslashes (\\) into single backslashes (\), 
    .replace(/\\\\/g, '\\')
    
    // remove the opening and closing forward slashes (/).
    // this needs to be more intelligent - what if there are flags?
    .slice(1, -1);

// there could be an invalid regular expression string
try {
  regexValue = eval('new RegExp("' + escapedLiteral + '")').toString();
} catch (e) {
  regexValue = null;
}

// should print "//"
document.writeln(regexValue);

I'm doing some JavaScript source code parsing and this difference is making things challenging.

Upvotes: 2

Views: 415

Answers (2)

Tamas Hegedus
Tamas Hegedus

Reputation: 29926

First, /\\x1f/ is not the same as new RegExp("\x1f"), it is rather new RegExp("\\\\x1f").

Second, if you are doing the eval hack, you could just feed back the string representation of the regex to eval:

var x = /\x1f/;
console.log(eval(''+x));

Third, there are a lot of JavaScript parsing libraries out there, like esprima, espree or babylon. I recommend using one of them, or at least study their source code.

To quickly avoid the eval hack, you could do something like:

var literalStr = "/abc/gi";
var m = /^\/(.*)\/([a-z]*)$/.exec(literalStr);
var regexObj = m ? new RegExp(m[1], m[2]) : null;
console.log(regexObj);

Upvotes: 1

Master DJon
Master DJon

Reputation: 1965

Or ...

/\x1f/.toString().replace(/\\x(..)/g, 
   function(a, b) {return a.replace("\\x" + b, String.fromCharCode(b));}
);

Upvotes: 0

Related Questions