在Ruby中按连续组划分

时间:2018-10-31 20:43:32

标签: ruby regex

我有下一个字符串:

txt = "HwwwwjjaoHHHHaffgd"

我需要通过对相同的连续字符进行分组来形成一个数组,以得到:

["H" "wwww" "jj" "a" "o" "HHHH" "a" "ff" "g" "d"]

3 个答案:

答案 0 :(得分:6)

有几种方法可以做到这一点。

txt = "Hwwww||333jjao{{\\HHHH@@affg//d"

txt.split(/(?<=(.))(?!\1)/).each_slice(2).map(&:first)

txt.each_char.slice_when(&:!=).map(&:join)

txt.each_char.chunk(&:itself).map { |_,a| a.join }

txt.each_char.chunk_while(&:==).map(&:join)

txt.gsub(/(?<=(.))(?!\1)/, ' ').split

txt.gsub(/(.)\1*/).reduce([], &:<<)  

txt[1..-1].each_char.with_object([txt[0]]) {|c,a| a.last[-1]==c ? (a.last<<c) : a << c}

以上所有回报

["H", "wwww", "||", "333", "jj", "a", "o", "{{", "\\", "HHHH", "@@", "a",
 "ff", "g", "//", "d"]

答案 1 :(得分:2)

让我们细分接受的答案:

str = "HwwwwjjaoHHHHaffgd"

str.scan(/((\w)\2*)/).map(&:first)

# => ["H", "wwww", "jj", "a", "o", "HHHH", "a", "ff", "g", "d"]

这是如何工作的?

.scan #from https://ruby-doc.org/core-2.2.0/String.html

#scan(pattern) 
#scan(pattern) {|match, ...| block } → str
  

这两种形式都通过str进行迭代,匹配模式(可能是   正则表达式或字符串)。对于每个匹配,都会生成一个结果,或者   添加到结果数组或传递给块。如果模式   不包含任何组,每个单独的结果均包含匹配项   字符串,$&。如果模式包含组,则每个单独的结果为   本身是一个数组,每个组包含一个条目。

使用的正则表达式模式

\w匹配任何任何单词字符(字母,数字,下划线) (\w)将其包装在括号内,也称为“捕获组”-括号将它们之间的正则表达式分组。它们将其中的正则表达式匹配的文本捕获到一个编号组中,该编号组可以与编号后向引用一起重复使用。它们允许您将正则表达式运算符应用于整个分组的正则表达式。

这就是您使用(\w)\2并将其传递到.scan内部的//的情况,它告诉扫描它是一个正则表达式,而不是纯字符串。

str.scan(/((\w)\2*)/) # will return the following array of arrays
[ ["H", "H"], ["wwww", "w"], ["jj", "j"], ["a", "a"], ["o", "o"], 
  ["HHHH", "H"], ["a", "a"], ["ff", "f"], ["g", "g"], ["d", "d"] ]

现在,您只需要每个数组中的第一项,因此您可以简单地调用.map 结果

str.scan(/((\w)\2*)/).map(&:first) # shorthand for 
str.scan(/((\w)\2*)/).map{|i| i.first}

#=> ["H", "wwww", "jj", "a", "o", "HHHH", "a", "ff", "g", "d"]

当您将来需要自己处理正则表达式时,这里有一些有用的资源。

https://www.regular-expressions.info/tutorial.html

这有点过时了,但通常有助于快速测试 http://rubular.com/

答案 2 :(得分:1)

基于@iGian的回复:

def split_by_chars
  scan(/((\w)\2*)/).map(&:first)
end

txt = "HwwwwjjaoHHH HHHaffgd"
txt.split_by_chars
# => ["H", "wwww", "jj", "a", "o", "HHH", "HHH", "a", "ff", "g", "d"]