匹配字符串中连续字符的序列

时间:2011-12-14 01:52:49

标签: ruby regex

我有字符串"111221",并希望匹配所有连续的相等整数集:["111", "22", "1"]

我知道有一个特殊的正则表达式可以做到这一点,但我不记得了,我在Googling很糟糕。

4 个答案:

答案 0 :(得分:12)

在Ruby 1.8.7 +中使用正则表达式:

p s.scan(/((\d)\2*)/).map(&:first)
#=> ["111", "22", "1"]

这是有效的,因为(\d)捕获任何数字,然后\2*捕获该组(第二个左括号)匹配的零或多个。在(…)中需要外部scan来捕获整个匹配。最后,scan单独返回:

[["111", "1"], ["22", "2"], ["1", "1"]]

...所以我们需要贯穿并保留每个数组中的第一项。在Ruby 1.8.6+中(为方便起见,它没有Symbol#to_proc):

p s.scan(/((\d)\2*)/).map{ |x| x.first }
#=> ["111", "22", "1"]

没有正则表达式,这是一个有趣的(匹配任何字符)在Ruby 1.9.2中工作:

p s.chars.chunk{|c|c}.map{ |n,a| a.join }
#=> ["111", "22", "1"]

这是另一个应该在Ruby 1.8.6中运行的版本:

p s.scan(/./).inject([]){|a,c| (a.last && a.last[0]==c[0] ? a.last : a)<<c; a }
# => ["111", "22", "1"]

答案 1 :(得分:0)

"111221".gsub(/(.)(\1)*/).to_a
  #=> ["111", "22", "1"]

这使用String#gsub的形式,该形式没有块,因此返回一个枚举数。似乎gsub在v2.0中已被授予该选项。

答案 2 :(得分:0)

我发现这有效,它首先匹配一组中的每个字符,然后匹配之后的任何相同字符。这将导致一个包含两个元素数组的数组,每个数组的第一个元素是初始匹配项,然后第二个元素是与第一个字符匹配的任何其他重复字符。这些数组重新组合在一起,得到一个重复字符数组:

input = "WWBWWWWBBBWWWWWWWB3333!!!!"
repeated_chars = input.scan(/(.)(\1*)/)
# => [["W", "W"], ["B", ""], ["W", "WWW"], ["B", "BB"], ["W", "WWWWWW"], ["B", ""], ["3", "333"], ["!", "!!!"]]
repeated_chars.map(&:join)
# => ["WW", "B", "WWWW", "BBB", "WWWWWWW", "B", "3333", "!!!!"]

作为替代方案,我发现我可以创建一个新的Regexp对象来匹配输入字符串中每个唯一字符的一个或多个出现,如下所示:

input = "WWBWWWWBBBWWWWWWWB3333!!!!"
regexp = Regexp.new("#{input.chars.uniq.join("+|")}+")
#=> regexp created for this example will look like: /W+|B+|3+|!+/

,然后使用该Regex对象作为scan的参数,以拆分出所有重复的字符,如下所示:

input.scan(regexp)
# => ["WW", "B", "WWWW", "BBB", "WWWWWWW", "B", "3333", "!!!!"]

答案 3 :(得分:-2)

你可以试试

string str ="111221";
string pattern =@"(\d)(\1)+";

希望可以帮到你