【问题标题】:How to convert a regular expression to a String literal and back again?如何将正则表达式转换为字符串文字并再次返回?
【发布时间】:2016-11-04 18:30:12
【问题描述】:

我该怎么做:

  1. 将带有标志的 JavaScript RegExp 转换为字符串文字(想想 JSON),
  2. 然后将该文字转换回正则表达式?

例如使用字符串"the weather is nice today":

var myRe = new RegExp("weather","gi");
var myReToString = myRe.toString(); // myReToString is now "/weather/gi"

var myReCopy = /* How to get this copy only from myReToString ? */

要修改原始 RegExp 属性,请参阅 torazaburo's answer

【问题讨论】:

  • 我问将正则表达式转换为字符串并再次转换回来的用例是什么?
  • 您的 .replace() 方法会破坏任何在实际表达式中包含正斜杠的正则表达式。此外,您的技术假定应始终使用 gi 标志。
  • eval 会做到的。
  • 完成。让我知道你的想法。另外,如果您不喜欢我的更改,请随时 edit 您的帖子或回滚我的更改。

标签: javascript regex


【解决方案1】:

你可以使用eval来取回正则表达式:

var myRe = RegExp("weather", "gi");
var myReString = myRe.toString();
eval(myReString); // => /weather/gi

注意:eval can execute arbitrary javascript expression. 仅当您确定字符串是从正则表达式 toString 方法生成时才使用 eval

【讨论】:

    【解决方案2】:

    查看RegExp 原型上的访问器属性,例如sourceflags。所以你可以这样做:

    var myRe = new RegExp("weather", "gi")
    
    var copyRe = new RegExp(myRe.source, myRe.flags); 
    

    有关规范,请参阅http://www.ecma-international.org/ecma-262/6.0/#sec-get-regexp.prototype.flags

    序列化和反序列化正则表达式

    如果您这样做的目的是将正则表达式序列化,例如转换为 JSON,然后将其反序列化,我建议将正则表达式存储为 [source, flags] 的元组,然后使用 new RexExp(source, flags) 重构它。这似乎比尝试使用正则表达式或评估它来分离它要干净一些。例如,您可以将其字符串化为

    function stringifyWithRegexp(o) {
      return JSON.stringify(o, function replacer(key, value) {
        if (value instanceof RegExp) return [value.source, value.flags];
        return value;
      });
    }
    

    在返回的路上,您可以使用JSON.parse 和 reviver 来取回正则表达式。

    修改正则表达式

    如果您想在保留标志的同时修改正则表达式,您可以使用修改后的源和相同的标志创建一个新的正则表达式:

    var re = /weather/gim;
    var newre = new RegExp(re.source + "| is", re.flags);
    

    【讨论】:

    • 重点是您无法访问原始正则表达式。
    • "然后再返回?" 表示来自字符串。第 1 步的输出是第 2 步的输入。
    • 因此向 OP 提出了他/她为什么需要这样做的问题。也许有更好的东西可以解决根本问题:)
    • 实际上你回答了我想问的问题,感谢@SWLim 要求澄清。因为这个问题的直接答案是 eval,所以我接受了它的答案,但是你的确实解决了我的问题,这在编辑中提到了你的答案
    • 没问题。请注意,我会避免使用 eval(Google 'javascript evil eval' 你会看到很多关于它的文章),但只要you know what you're dealing with 应该没问题。
    【解决方案3】:

    我不确定这段代码是否适用于所有情况,但我确信这可以使用正则表达式来完成:

    var regex = new RegExp('^/(.+)/(.*)$')
    function stringToRegex(s) {
        var match = s.match(regex)
        return new RegExp(match[1], match[2])
    }
    
    var test = new RegExp("weather", "gi")
    
    console.log(stringToRegex(test.toString()))
    console.log(stringToRegex(test.toString()).toString() === test.toString())

    Debuggex Demo

    【讨论】:

    • 我很确定这在所有情况下都有效,因为.+ 是贪婪的。第二个/ 只会匹配字符串中的最后一个。
    猜你喜欢
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2015-01-19
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 2012-01-28
    相关资源
    最近更新 更多