RegExp转到字符串然后返回时出现意外行为

时间:2018-08-09 10:36:51

标签: javascript regex serialization deserialization

我需要序列化一些javascript正则表达式。

我的计划是使用.toString()进行序列化,然后使用new RegExp(string)进行反序列化,但是这并不像我期望的那样-字符串/中的正则表达式定界符被{转义了{1}}。这是一个示例:

new RegExp()

返回以下内容:

let regEx = /^[A-Z][A-Z-\\.]+$/g;
console.log("Initial: " + regEx.source);
    
let regExString = regEx.toString();
console.log("toString(): " + regExString);
    
let nRegEx = new RegExp(regExString);
console.log("new RegExp from string:" + nRegEx.source);

如果我改为这样做("Initial: ^[A-Z][A-Z-\\.]+$" "toString(): /^[A-Z][A-Z-\\.]+$/g" "new RegExp from string:\/^[A-Z][A-Z-\\.]+$\/g" ):

regEx.source.toString()

结果为:

let regEx = /^[A-Z][A-Z-\\.]+$/g;
console.log("Initial: " + regEx.source);
    
let regExString = regEx.source.toString();
console.log("toString(): " + regExString);
   
let nRegEx = new RegExp(regExString);
console.log("new RegExp from string:" + nRegEx.source);

哪个更好,但在本例"Initial: ^[A-Z][A-Z-\\.]+$" "toString(): ^[A-Z][A-Z-\\.]+$" "new RegExp from string:^[A-Z][A-Z-\\.]+$"

中会丢失我的所有标志

我该怎么做才能使这项工作成功?

2 个答案:

答案 0 :(得分:1)

也许不是最优雅的解决方案,但是您可以将toString的结果分为RE和修饰符,例如:

let regEx = /^[A-Z][A-Z-\\.]+$/g;
console.log("Initial: " + regEx.source);
    
let regExString = regEx.toString();
console.log("toString(): " + regExString);

let arrRegEx = regExString.split('/');

let nRegEx = new RegExp(arrRegEx[1], arrRegEx[2]);
console.log("new RegExp from string:" + nRegEx.source);
console.log("global: " + nRegEx.global ? 'true' : 'false');

(请注意,使用split会将第一个索引留空。因此,索引1和2作为new的输入。)

修改

如果RE中有乱扔的/,则上述操作将失败。使用正则表达式提取零件可以解决以下问题:

    let regEx = /^[A-Z][A-Z-\/\\.]+$/gi;
    console.log("Initial: " + regEx.source);
        
    let regExString = regEx.toString();
    console.log("toString(): " + regExString);

    let arrRegEx = /^\/(.*)\/([gmi]*)/.exec(regExString);
    console.log("RegEx:" + arrRegEx[1] + ", flags:" + arrRegEx[2]);

    let nRegEx = new RegExp(arrRegEx[1], arrRegEx[2]);
    console.log("new RegExp from string:" + nRegEx.source);
    console.log("global: " + nRegEx.global);
    console.log("ignoreCase: " + nRegEx.ignoreCase);
    console.log("multiline: " + nRegEx.multiline);

答案 1 :(得分:0)

使用原始正则表达式对象的.source.flags属性来构造新的RegExp对象:

let regEx = /^[A-Z][A-Z\\.-]+$/g
console.log(regEx.toString())
//=> /^[A-Z][A-Z\\.-]+$/g

let nRegEx = new RegExp(regEx.source, regEx.flags)
console.log(nRegEx.toString())
//=> /^[A-Z][A-Z\\.-]+$/g