从正则表达式文本中获取正则表达式字符串表示的最佳方式

Best way to get string representation of regex from regex literal

本文关键字:正则表达式 最佳 方式 表示 获取 文本 字符串      更新时间:2023-09-26

如果我这样做:

// note that 'x1f is a control character
var regex = new RegExp("'x1f");
// prints "//"
console.log(regex.toString()); 

如果我改为这样做:

var regex = /''x1f/;
// prints "/''x1f/"
console.log(regex.toString());

我希望能够从第二个正则表达式中获得第一个结果(//-一个带有控制字符的字符串)。有简单的方法吗?到目前为止,我只能用一个恶心的eval破解来做到这一点:

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

我正在做一些JavaScript源代码解析,这种差异使事情变得很有挑战性。

首先,/''x1f/new RegExp("'x1f")不同,而是new RegExp("''''x1f")

其次,如果你正在进行eval破解,你可以将正则表达式的字符串表示反馈给eval:

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

第三,有很多JavaScript解析库,比如esprima、espree或babylon。我建议使用其中一个,或者至少研究它们的源代码。

为了快速避免eval黑客攻击,你可以做一些类似的事情:

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

或者。。。

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