【问题标题】:Replace string between first and second occurrence of forward slash在第一次和第二次出现正斜杠之间替换字符串
【发布时间】:2020-05-28 15:18:30
【问题描述】:

我对正则表达式不是很熟悉,我需要帮助替换其中第一次和第二次出现正斜杠之间的字符串值。

示例

const str = '/questions/ask/1'
const strReplace = str.replace(/\[.*?\]\s?/g, 'example')

输出:

  1. /questions/ask/1 /example/ask/1
  2. /questions-math/ask/1 /example/ask/1

我似乎无法获得正确的正则表达式。 谢谢你的帮助。我知道有很多类似的问题,但我找不到解决方案。

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    var s = '/questions/ask/1';
    var s2 = '/questions-math/ask/1';
    var r = s.replace(/[^\/][-a-zA-Z]*/, 'example');
    var r2 = s2.replace(/[^\/][-a-zA-Z]*/, 'example');
    console.log(r);
    console.log(r2);

    编辑:

    懒惰与贪婪的问题。

    出于某种难以理解的原因,有一种使用惰性模式正则表达式的时尚。这样的表达方式并不是万能的。在这种情况下,使用默认的贪婪模式表达式使它们更易于使用和开发。

    “更高的性能”也是一个神话,想想所使用的算法,但为了说明,我通过计算 100 次测试的平均值来比较这些解决方案,每次 100 万次替换

    I. 10-year PC, CPU 4 core 23145.70 BogoMIPS
    Greedy:  278 ms
    Lazy:    900 ms
    
    II. 30-year PC, CPU 1 core 3397.11 BogoMIPS
    Greedy:  6736 ms
    Lazy:    7490 ms
    

    如您所见,坚定不移的表达式结果变得更慢,并且这种差异随着处理器功率的增加而急剧增加。

    请注意,这些差异与 100 万次替换有关,其中一次替换完全没有意义。

    当然,并非所有情况都如此。 如果我们关心一个函数的性能,没有捷径可走,只有通过profiling进行测量才能给出答案。

    【讨论】:

    • 这行得通!有没有办法排除特殊字符,例如字符串是否有 - 示例: /questions-math/ask/1 **to ** /example/ask/1
    • 只需将这些字符添加到 [] 之间的字符范围内,在这种情况下为 [-a-zA-Z]
    • @Mandy8055 “更高效”,这种“优化”的目的是什么?在我使用了 10 年的笔记本电脑上,271 毫秒内发生了 100 万次替换。
    【解决方案2】:

    像这样使用简单的 JS 可能会更好:

    var str = '/questions/ask/1';
    var res = str.split("/");
    res[1] = 'example';
    res = res.join("/");
    

    【讨论】:

      【解决方案3】:

      如果字符串中必须有第二个正斜杠存在

      ^\/[^\/\r\n]+(?=\/)
      

      解释

      • ^ 字符串开始
      • \/匹配第一个/
      • [^\/\r\n]+ 匹配除 / 或换行符以外的任何字符 1 次以上
      • (?=\/)正向前瞻,断言右边是第二个/

      Regex demo

      在替换中使用第一个/,后跟example

      [
        '/questions/ask/1',
        '/questions/',
        '/questions'
      ].forEach(s =>
        console.log(s + " --> " + s.replace(/^\/[^\/\r\n]+(?=\/)/, "/example"))
      )

      【讨论】:

      • 在我看来,这个正则表达式是最有效和推荐的。
      【解决方案4】:

      您可以使用以下正则表达式:

      ^(\/)(?:[-\w!#$]+)(.*?)$
      

      正则表达式的解释:

      ^ - 表示给定字符串的开始。

      (\/) - 代表 1st 捕获组。该组在替换中用作$1

      (?:[-\w!#$]+) - 代表一个非捕获组,因为您需要替换它包含单词字符和所有需要替换一次或多次的特殊符号. 您可以在此处添加其他需要排除的特殊符号。

      (.*?) - 代表 2nd 捕获组捕获除替换后的换行符 lazily 之外的所有内容。该组在替换中用作$2

      $ - 表示给定测试字符串的结尾。

      你可以在here.找到上述正则表达式的demo

      在 JAVASCRIPT 中的实现:

      const regex = /^(\/)(?:[-\w!#$]+)(.*?)$/gm;
      const str = `/questions-math/ask/1
      /questions/ask/1`;
      const subst = `$1examples$2`;
      
      // The substituted value will be contained in the result variable
      const result = str.replace(regex, subst);
      
      console.log(result);

      【讨论】:

        猜你喜欢
        • 2022-10-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-02
        • 1970-01-01
        相关资源
        最近更新 更多