Match sequences of consecutive characters in a string

前端 未结 4 1791
粉色の甜心
粉色の甜心 2020-12-19 05:31

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

I know that there is a spe

相关标签:
4条回答
  • 2020-12-19 06:19

    I found that this works, it first matches each character in one group, and then it matches any of the same character after it. This results in an array of two element arrays, with the first element of each array being the initial match, and then the second element being any additional repeated characters that match the first character. These arrays are joined back together to get an array of repeated characters:

    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", "!!!!"]
    

    As an alternative I found that I could create a new Regexp object to match one or more occurrences of each unique characters in the input string as follows:

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

    and then use that Regex object as an argument for scan to split out all the repeated characters, as follows:

    input.scan(regexp)
    # => ["WW", "B", "WWWW", "BBB", "WWWWWWW", "B", "3333", "!!!!"]
    
    0 讨论(0)
  • 2020-12-19 06:23

    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"]
    
    0 讨论(0)
  • 2020-12-19 06:23
    "111221".gsub(/(.)(\1)*/).to_a
      #=> ["111", "22", "1"]
    

    This uses the form of String#gsub that does not have a block and therefore returns an enumerator. It appears gsub was bestowed with that option in v2.0.

    0 讨论(0)
  • 2020-12-19 06:26

    you can try is

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

    Hope can help you

    0 讨论(0)
提交回复
热议问题