Ruby: How to count the number of times a string appears in another string?

前端 未结 3 1711
轻奢々
轻奢々 2021-02-01 12:07

I\'m trying to count the number of times a string appears in another string.

I know you can count the number of times a letter appears in a string:

strin         


        
相关标签:
3条回答
  • 2021-02-01 12:43

    Here are a couple of ways to count the numbers of times a given substring appears in a string (the first being my preference). Note (as confirmed by the OP) the substring 'aa' appears twice in the string 'aaa', and therefore five times in:

    string="aaabbccaaaaddbb"
    

    #1

    Use String#scan with a regex that contains a positive lookahead that looks for the substring:

    def count_em(string, substring)
      string.scan(/(?=#{substring})/).count
    end
    
    count_em(string,"aa")
     #=> 5
    

    Note:

    "aaabbccaaaaddbb".scan(/(?=aa)/)
      #=> ["", "", "", "", ""]
    

    A positive lookbehind produces the same result:

    "aaabbccaaaaddbb".scan(/(?<=aa)/)
      #=> ["", "", "", "", ""]
    

    As well, String#scan can be replaced with String#gsub.

    #2

    Convert to an array, apply Enumerable#each_cons, then join and count:

    def count_em(string, substring)
      string.each_char.each_cons(substring.size).map(&:join).count(substring)
    end
    
    count_em(string,"aa")
      #=> 5
    

    We have:

    enum0 = "aaabbccaaaaddbb".each_char
      #=> #<Enumerator: "aaabbccaaaaddbb":each_char>
    

    We can see the elements that will generated by this enumerator by converting it to an array:

    enum0.to_a
      #=> ["a", "a", "a", "b", "b", "c", "c", "a", "a", "a",
      #    "a", "d", "d", "b", "b"]
    
    enum1 = enum0.each_cons("aa".size)
      #=> #<Enumerator: #<Enumerator: "aaabbccaaaaddbb":each_char>:each_cons(2)> 
    

    Convert enum1 to an array to see what values the enumerator will pass on to map:

    enum1.to_a
      #=> [["a", "a"], ["a", "a"], ["a", "b"], ["b", "b"], ["b", "c"],
      #    ["c", "c"], ["c", "a"], ["a", "a"], ["a", "a"], ["a", "a"], 
      #    ["a", "d"], ["d", "d"], ["d", "b"], ["b", "b"]]
    
    c = enum1.map(&:join)
      #=> ["aa", "aa", "ab", "bb", "bc", "cc", "ca",
      #    "aa", "aa", "aa", "ad", "dd", "db", "bb"]
    c.count("aa")
      #=> 5
    
    0 讨论(0)
  • 2021-02-01 12:49

    It's because the count counts characters, not instances of strings. In this case 'aa' means the same thing as 'a', it's considered a set of characters to count.

    To count the number of times aa appears in the string:

    string = "aabbccddbb"
    string.scan(/aa/).length
    # => 1
    string.scan(/bb/).length
    # => 2
    string.scan(/ff/).length
    # => 0
    
    0 讨论(0)
  • 2021-02-01 13:00

    try to use string.split('a').count - 1

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