我有下一个字符串:
txt = "HwwwwjjaoHHHHaffgd"
我需要通过对相同的连续字符进行分组来形成一个数组,以得到:
["H" "wwww" "jj" "a" "o" "HHHH" "a" "ff" "g" "d"]
答案 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"]