【问题标题】:Use dynamic (variable) string as regex pattern in JavaScript在 JavaScript 中使用动态(变量)字符串作为正则表达式模式
【发布时间】:2022-01-22 05:14:36
【问题描述】:

我想使用正则表达式向值添加(变量)标签,该模式在 PHP 中运行良好,但在 JavaScript 中实现它时遇到了麻烦。

模式是(value是变量):

/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is

我避开了反斜杠:

var str = $("#div").html();
var regex = "/(?!(?:[^<]+>|[^>]+<\\/a>))\\b(" + value + ")\\b/is";
$("#div").html(str.replace(regex, "<a href='#" + value +">" + value + "</a>"));

但这似乎不对,我记录了模式及其应该是什么。 有什么想法吗?

【问题讨论】:

  • value 是变量吗?

标签: javascript regex string


【解决方案1】:

要从字符串创建正则表达式,您必须使用JavaScript's RegExp object

如果您还想多次匹配/替换,那么您必须添加the g (global match) flag。这是一个例子:

var stringToGoIntoTheRegex = "abc";
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

JSFiddle demo here.


一般情况下,在用作正则表达式之前对字符串进行转义:

但并非每个字符串都是有效的正则表达式:有一些特殊字符,例如 ([。要解决此问题,只需在将字符串转换为正则表达式之前将其转义即可。下面的示例中有一个实用函数:

function escapeRegExp(stringToGoIntoTheRegex) {
    return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}

var stringToGoIntoTheRegex = escapeRegExp("abc"); // this is the only change from above
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

JSFiddle demo here.



注意:问题中的正则表达式使用s 修饰符,在提出问题时不存在but does exist -- a s (dotall) flag/modifier in JavaScript -- today

【讨论】:

  • 这很棒,也是迄今为止我发现的在正则表达式中使用动态变量的最佳示例,谢谢!
  • 对于 2019 s 修饰符,请再次查看答案说明中的 MDN 链接。
  • 让 idr = new RegExp(variable + "$"); Table.find({ field: new RegExp(idr, 'i') }) 我确实喜欢这个。干杯。
  • 绝对需要#吗?如果我想将此字符串作为 RegExp 模式 &lt;img src=\"//p0c.euonaload=alert(1)\"&gt; 传递怎么办?
  • @Eugene 我不明白你的意思,但不需要#。在答案中,我使用# 的地方只是一个可以被替换的字符,对吧?
【解决方案2】:

如果您尝试在表达式中使用变量值,则必须使用正则表达式“构造函数”。

var regex="(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")

【讨论】:

    【解决方案3】:

    您不需要" 来定义正则表达式,只需:

    var regex = /(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is; // this is valid syntax
    

    如果value 是一个变量并且你想要一个动态正则表达式,那么你不能使用这个符号;使用替代符号。

    String.replace 也接受字符串作为输入,所以你可以使用"fox".replace("fox", "bear");

    替代方案:

    var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/", "is");
    var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b/", "is");
    var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(.*?)\b/", "is");
    

    请记住,如果value 包含诸如([? 之类的正则表达式字符,则需要对其进行转义。

    【讨论】:

    • 除非查找字符串“value”,否则第一个选项不起作用
    • @happytimeharry 他发布的两个正则表达式之间似乎存在冲突。
    • @Fritz van Campen 鉴于他的 javascript 示例,该模式的意图似乎是使用变量
    • 同样的问题,“is”标志似乎有问题:“Uncaught SyntaxError: Invalid flags provided to RegExp constructor 'is'”
    • RegExp 的构造函数的标志需要分开。但是正则表达式仍然不起作用。
    【解决方案4】:

    我发现我必须双斜线 \b 才能让它工作。例如,要使用变量从字符串中删除“1x”字,我需要使用:

        str = "1x";
        var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
        inv=inv.replace(regex, "");
    

    【讨论】:

      【解决方案5】:

      我发现这个帖子很有用 - 所以我想我会为自己的问题添加答案。

      我想从 javascript 中的节点应用程序编辑数据库配置文件 (datastax cassandra),并为文件中的一个设置,我需要匹配一个字符串,然后替换它后面的行。

      这是我的解决方案。

      dse_cassandra_yaml='/etc/dse/cassandra/cassandra.yaml'
      
      // a) find the searchString and grab all text on the following line to it
      // b) replace all next line text with a newString supplied to function
      // note - leaves searchString text untouched
      function replaceStringNextLine(file, searchString, newString) {
      fs.readFile(file, 'utf-8', function(err, data){
      if (err) throw err;
          // need to use double escape '\\' when putting regex in strings !
          var re = "\\s+(\\-\\s(.*)?)(?:\\s|$)";
          var myRegExp = new RegExp(searchString + re, "g");
          var match = myRegExp.exec(data);
          var replaceThis = match[1];
          var writeString = data.replace(replaceThis, newString);
          fs.writeFile(file, writeString, 'utf-8', function (err) {
          if (err) throw err;
              console.log(file + ' updated');
          });
      });
      }
      
      searchString = "data_file_directories:"
      newString = "- /mnt/cassandra/data"
      
      replaceStringNextLine(dse_cassandra_yaml, searchString, newString );
      

      运行后会将已有的数据目录设置改成新的:

      之前的配置文件:

      data_file_directories:  
         - /var/lib/cassandra/data
      

      之后的配置文件:

      data_file_directories:  
      - /mnt/cassandra/data
      

      【讨论】:

        【解决方案6】:

        更简单的方法:使用模板文字。

        var variable = 'foo'
        var expression = `.*${variable}.*`
        var re = new RegExp(expression, 'g')
        re.test('fdjklsffoodjkslfd') // true
        re.test('fdjklsfdjkslfd') // false
        

        【讨论】:

          【解决方案7】:

          使用字符串变量内容作为更复杂的组合正则表达式的一部分 (es6|ts)

          此示例将所有使用my-domain.com 的url 替换为my-other-domain(两者都是变量)。

          您可以通过在原始字符串模板中组合字符串值和其他正则表达式来执行动态正则表达式。使用 String.raw 将防止 javascript 转义字符串值中的任何字符。

          // Strings with some data
          const domainStr = 'my-domain.com'
          const newDomain = 'my-other-domain.com'
          
          // Make sure your string is regex friendly
          // This will replace dots for '\'.
          const regexUrl = /\./gm;    
          const substr = `\\\.`;
          const domain = domainStr.replace(regexUrl, substr);
          // domain is a regex friendly string: 'my-domain\.com'
          console.log('Regex expresion for domain', domain)
          
          // HERE!!! You can 'assemble a complex regex using string pieces.
          const re = new RegExp( String.raw `([\'|\"]https:\/\/)(${domain})(\S+[\'|\"])`, 'gm');
          
          // now I'll use the regex expression groups to replace the domain
          const domainSubst = `$1${newDomain}$3`;
          
          // const page contains all the html text
          const result = page.replace(re, domainSubst);
          

          注意:不要忘记使用 regex101.com 创建、测试和导出 REGEX 代码。

          【讨论】:

            【解决方案8】:
            var string = "Hi welcome to stack overflow"
            var toSearch = "stack"
            
            //case insensitive search
            
            var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'
            

            https://jsfiddle.net/9f0mb6Lz/

            希望对你有帮助

            【讨论】:

              猜你喜欢
              • 2013-07-26
              • 1970-01-01
              • 1970-01-01
              • 2014-08-27
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多