Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.1k views
in Technique[技术] by (71.8m points)

ruby - Match sequences of consecutive characters in a string

I have the string "111221" and want to match all sets of consecutive equal integers: ["111", "22", "1"].

I know that there is a special regex thingy to do that but I can't remember and I'm terrible at Googling.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Using regex in Ruby 1.8.7+:

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

This works because (d) captures any digit, and then 2* captures zero-or-more of whatever that group (the second opening parenthesis) matched. The outer (…) is needed to capture the entire match as a result in scan. Finally, scan alone returns:

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

…so we need to run through and keep just the first item in each array. In Ruby 1.8.6+ (which doesn't have Symbol#to_proc for convenience):

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

With no Regex, here's a fun one (matching any char) that works in Ruby 1.9.2:

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

Here's another version that should work even in 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"]

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...