【问题标题】:How to split a string by grouping consecutive same chars如何通过对连续的相同字符进行分组来拆分字符串
【发布时间】:2020-02-27 22:11:20
【问题描述】:

我有一串连续的相同字符,例如:“aaabbc”,我想将它们分组到一个数组中:[“aaa”,“bb”,“c”]。

我已经尝试使用 Hash 来解决它,并且确实有效,但现在我想知道是否可以使用 split 和 regex 来解决。

这是我根据 SO 的另一个答案所做的:

"aaabbc".split(/\\b([a-z])\\1+\\b/)

但它只给了我数组中的初始字符串:

["aaabbc"] 

而不是给每组相同的连续字符用逗号分隔:

["aaa", "bb", "c"]

【问题讨论】:

    标签: regex ruby split


    【解决方案1】:

    您也可以使用String#scan。 它比gsub 方法有点混乱,正如上面的答案所暗示的那样:

    "aaabbbbc".scan(/(.)(\1*)/)
      #=> [["a", "aa"], ["b", "bbb"], ["c", ""]]
    

    因为scan 将匹配项收集在单独的数组中,所以第一个匹配组(.) 每次都是独立的,但join 组起来很简单:

    "aaabbbbc".scan(/(.)(\1*)/).map(&:join)
     #=> ["aaa", "bbbb", "c"]
    
    

    【讨论】:

      【解决方案2】:
      "aaabbc".gsub(/(.)\1*/).to_a
        #=> ["aaa", "bb", "c"] 
      

      当没有给出块时,这使用String#gsub 的形式,在这种情况下返回一个枚举器。其实gsub这种形式与字符串替换无关;枚举器仅生成匹配项。当存在捕获组时,它克服了String#scan 的限制。

      正则表达式为“匹配任意字符,将其保存在捕获组 1 中,然后匹配零个或多个等于捕获组 1 内容的字符”。

      【讨论】:

      • 嗨 可以解释一下这个(.)\1*+ 正则表达式是如何工作的吗?
      • @Rajagopalan +possessive modifier,意思是拿走你能找到的所有东西,如果你找不到匹配项,就不要归还任何东西。它唯一能做的就是加快正则表达式的速度,因为它不需要回溯那个量词。
      • @3limin4t0r,我承认+ 是我忘记删除的遗物。 :-) 事实上,我并不知道“所有格修饰语”,所以学到了一些东西。我拿出了'+' 以保持简单。 3lim,谢谢你的解释。
      • @CarySwoveland 我也学到了一些东西,我总是忘记gsub 可以与一个参数一起使用。这可能是由于sub = 我心中的替代名称。我会尽量记住这个,这是一个干净的解决方案。
      • @3limin4t0r,我发现在没有块的情况下使用gsub 有很多用途。我认为如果它是一个单独的方法,它会有更广泛的用途,例如String#each_match,在这种情况下就不需要gsub的那种形式,但是以这种方式改变gsub为时已晚。
      【解决方案3】:

      此答案不使用split,但提供了另一种选择。你可以使用Enumerable#chunk_while:

      "aaabbc".each_char.chunk_while(&:==).map(&:join)
      #=> ["aaa", "bb", "c"]
      

      这首先将字符串拆分为一个字符列表,然后使用== 比较连续的元素。这将创建一个字符数组数组。最后,使用join 将每个字符数组转换回字符串。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-30
        • 2013-03-03
        • 2015-05-18
        • 1970-01-01
        • 1970-01-01
        • 2016-04-28
        • 1970-01-01
        相关资源
        最近更新 更多