【问题标题】:Remove all occurrences except last?删除除最后一个以外的所有匹配项?
【发布时间】:2012-03-14 01:58:32
【问题描述】:

我想删除字符串中所有出现的 substring = .,除了最后一个。

例如:

1.2.3.4

应该变成:

123.4

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    您可以使用正则表达式积极向前看,

    "1.2.3.4".replace(/[.](?=.*[.])/g, "");
    

    【讨论】:

    • 这应该是公认的答案。用英语说这个,正则表达式说“匹配所有出现的 . 后面有另一个 . ”,然后你只需用空字符串替换。您偶尔会听到有人抱怨正则表达式的可读性不如从数组中进行大拆分然后格式化,但很容易在上面的评论中简单地描述您的正则表达式。
    • 我认为在孤立的性能测试中投入过多的库存是不明智的,因为引擎在优化方面不会那么聪明,但积极的前瞻似乎并不能很好地扩展。在这里,我发现短字符串('1.2.3.4' 示例)与拆分数组相比要快得多,但在较长的字符串上却落后了很多:jsperf.com/removing-all-but-last-string-token
    【解决方案2】:

    2 线:

    function removeAllButLast(string, token) {
        /* Requires STRING not contain TOKEN */
        var parts = string.split(token);
        return parts.slice(0,-1).join('') + token + parts.slice(-1)
    }
    

    不需要字符串参数的替代版本:

    function removeAllButLast(string, token) {
        var parts = string.split(token);
        if (parts[1]===undefined)
            return string;
        else
            return parts.slice(0,-1).join('') + token + parts.slice(-1)
    }
    

    演示:

    > removeAllButLast('a.b.c.d', '.')
    "abc.d"
    

    下面的单行是一个正则表达式,它利用了* 字符是贪婪的这一事实,如果没有找到匹配项,则替换将单独保留字符串。它通过匹配 [包括点的最长字符串] [点] 并留下 [字符串的其余部分] 来工作,如果找到匹配项,它会从中删除所有 '.':

    'a.b.c.d'.replace(/(.*)\./, x => x.replace(/\./g,'')+'.')
    

    (如果您的字符串包含换行符,则必须使用[.\n] 而不是裸.s)

    【讨论】:

    • 仅供参考:如果有人需要删除所有但首先使用 >>> function removeAllButFirst(string, token) { var parts = string.split(token); return parts.slice(0,1) + token + parts.slice(1).join(''); }
    • 附加信息,如果字符串不包含令牌,则会被添加。
    • @Ello:感谢您的发现,添加了修复和正则表达式方法。
    【解决方案3】:

    你可以这样做:

    var str = '1.2.3.4';
    var last = str.lastIndexOf('.');
    var butLast = str.substring(0, last).replace(/\./g, '');
    var res = butLast + str.substring(last);
    

    活生生的例子:

    【讨论】:

      【解决方案4】:

      您可以积极向前看(保留最后一个点,如果有的话)并替换第一个出现的点。

      var string = '1.2.3.4';
      
      console.log(string.replace(/\.(?=.*\.)/g, ''));

      【讨论】:

        【解决方案5】:

        replaceAllButLast 函数比 removeAllButLast 函数更有用。当您要删除时,只需替换为空字符串:

        function replaceAllButLast(str, pOld, pNew) {
          var parts = str.split(pOld)
          if (parts.length === 1) return str
          return parts.slice(0, -1).join(pNew) + pOld + parts.slice(-1)
        }
        
        var test = 'hello there hello there hello there'
        test = replaceAllButLast(test, ' there', '')
        
        console.log(test) // hello hello hello there

        【讨论】:

          【解决方案6】:

          找到了一种更好的方法。这是replaceAllButLastappendAllButLast,因为他们应该这样做。后者在保留原始匹配的同时进行替换。要删除,只需替换为空字符串即可。

          var str = "hello there hello there hello there"
          
          function replaceAllButLast(str, regex, replace) {
            var reg = new RegExp(regex, 'g')
            return str.replace(reg, function(match, offset, str) {
                var follow = str.slice(offset);
                var isLast = follow.match(reg).length == 1;
                return (isLast) ? match : replace
            })
          }
          
          function appendAllButLast(str, regex, append) {
            var reg = new RegExp(regex, 'g')
            return str.replace(reg, function(match, offset, str) {
                var follow = str.slice(offset);
                var isLast = follow.match(reg).length == 1;
                return (isLast) ? match : match + append
            })
          }
          
          var replaced = replaceAllButLast(str, / there/, ' world')
          console.log(replaced)
          
          var appended = appendAllButLast(str, / there/, ' fred')
          console.log(appended)

          感谢@leaf 为他提供的这些杰作here

          【讨论】:

            【解决方案7】:

            您可以反转字符串,删除除第一个之外的所有子字符串,然后再次反转它以获得您想要的。

            【讨论】:

            • 是什么让您认为删除除第一个以外的所有出现比反之更容易?
            • 循环遍历字符串,更容易维护一个标志以知道第一个已经通过,我们现在可以继续删除所有出现的事件。比使用 str.charAt 方法反向循环字符串更容易和更易读。您始终可以使用 str.lastIndexOf 记住上次出现的位置,但是随着您删除之前出现的任何子字符串,该位置会不断变化,因此需要重新计算。
            • 一个反向循环比两次调用 reverse 更好
            【解决方案8】:
            function formatString() {
              var arr = ('1.2.3.4').split('.');
              var arrLen = arr.length-1;
              var outputString = '.' + arr[arrLen];
              for (var i=arr.length-2; i >= 0; i--) {
                 outputString = arr[i]+outputString;
              }
              alert(outputString);
            }
            

            在此处查看实际操作:http://jsbin.com/izebay

            【讨论】:

              【解决方案9】:

              var s='1.2.3.4';

              s=s.split('.');
              s.splice(s.length-1,0,'.');
              s.join('');
              

              123.4

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2011-03-28
                • 2013-03-16
                • 1970-01-01
                • 1970-01-01
                • 2022-11-23
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多