【问题标题】:Regex to match all '&' before first '?'正则表达式匹配第一个 '?' 之前的所有 '&'
【发布时间】:2009-01-26 13:03:13
【问题描述】:

基本上,我想做“zipzam&&&?&&&?&&&”->“zipzam%26%26%26?&&&?&&&”。我可以在没有正则表达式的情况下通过许多不同的方式来做到这一点,但如果我能用正则表达式来做的话,它会稍微清理一下。

谢谢

编辑:"zip=zam&&&=?&&&?&&&" -> "zip=zam%26%26%26=?&&&?&&&" 应该让事情更清楚一些。

编辑:"zip=zam=&=&=&=?&&&?&&&" -> "zip=zam=%26=%26=%26=?&&&?&&&" 应该让事情更清楚。

但是,这些只是示例。我仍然想在第一个 '?' 之前替换 all '&'无论第一个“?”之前的“&”在哪里并且不管 '&' 是否连续。

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    应该这样做:

    "zip=zam=&=&=&=?&&&?&&&".replace(/^[^?]+/, function(match) { return match.replace(/&/g, "%26"); });
    

    【讨论】:

    • @Gumbo 我认为你的最后一个可以解决问题。让我仔细检查一下。
    • @Gumbo 谢谢。最后一个做到了。而且,如果没有'?现在,它将所有 & 变成 %26,这也是我想要的。
    • 不错的简单半递归解决方案,比我的努力更好地呈现 +1 :)
    【解决方案2】:

    您需要在 JS 中难以复制的负面回溯,但幸运的是有一些方法和手段:

    var x = "zipzam&&&?&&&?&&&";
    
    x.replace(/(&+)(?=.*?\?)/,function ($1) {for(var i=$1.length, s='';i;i--){s+='%26';} return s;})
    

    commentary:这行得通,因为它不是全局的。因此,第一个匹配项是给定的,并且通过函数循环实现了将所有匹配的“&”字符 1:1 替换为“%26”的技巧


    编辑:只需稍作修改即可简单地(如果可能有点笨拙)实现“&”的未知分组的解决方案。替换方法的基本模式是无限灵活的。

    var x = "zipzam&foo&bar&baz?&&&?&&&";
    
    var f = function ($1,$2)
    {
      return $2 + ($2=='' || $2.indexOf('?')>-1 ? '&' : '%26')
    }
    
    x.replace(/(.*?)&(?=.*?\?)/g,f)
    

    【讨论】:

    • 这似乎产生了我想要的结果: alert("zip=zam&&&=?&&&?&&&".replace(/(&+)(?=.*?\?)/, encodeURIComponent) );但是,我错过了什么吗?
    • @Will - WFM,产生“zipzam%26%26%26?&&&?&&&”
    • 不知道为什么我会得到不同的结果。我会向你们鞠躬。
    • @Shadow - 不,这对你来说可能是一个干净的解决方案。在这种情况下,encodeURIComponent 方法将获得与上述 anon 方法相同的结果,因为该方法的第一个参数仍然是匹配项,您获得了内置处理,但失去了一些灵活性。这是一个很好的解决方案
    • @Will - 我只是在编辑器的 html 页面上运行它,无法想象为什么你会看到不同的东西?
    【解决方案3】:

    应该这样做:

    ^[^?]*&[^?]*\?
    

    【讨论】:

    • 我不确定您将如何使用此模式来实现目标,
    【解决方案4】:

    或者这个,我想:

    ^[^?]*(&+?)\?
    

    【讨论】:

    • @Will,我的想法是匹配组中的“&”。
    【解决方案5】:

    在这种情况下,正则表达式确实不是最适合使用的东西。简单搜索“?”的第一个索引然后替换每个 '&' 字符将是最好的。但是,如果您真的想要一个正则表达式,那么这应该可以完成工作。

    (?:.*?(&))*?\?
    

    【讨论】:

      【解决方案6】:

      这足够接近你所追求的:-

      alert("zipzam&&&?&&&?&&&".replace(/^([^&\?]*)(&*)\?/, function(s, p, m)
      {
      for (var i = 0; i < m.length; i++) p += '%26';
      return  p +'?';
      }));
      

      【讨论】:

      • 我认为我的测试结果不正确。我正在删除我所有的 cmets。
      【解决方案7】:

      由于 OP 只想在第一个问号之前匹配 & 符号,稍微修改 Michael Borgwardt 的答案给了我这个似乎合适的正则表达式:

      ^[^?&]*(\&+)\?
      

      用“%26”替换所有匹配项

      这将不匹配 zipzam&&abc?&&&?&&& 因为第一个“?”前面没有 & 符号。

      【讨论】:

        猜你喜欢
        • 2017-10-28
        • 1970-01-01
        • 1970-01-01
        • 2023-03-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多