Reputation: 12814
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
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
Reputation: 1965
Or ...
/\x1f/.toString().replace(/\\x(..)/g,
function(a, b) {return a.replace("\\x" + b, String.fromCharCode(b));}
);
Upvotes: 0