Ruby:如何计算字符串出现在另一个字符串中的次数?

Joh*_*son 45 ruby string count

我正在尝试计算字符串出现在另一个字符串中的次数.

我知道你可以计算字母出现在字符串中的次数:

string = "aabbccddbb"
string.count('a')
=> 2
Run Code Online (Sandbox Code Playgroud)

但是如果我搜索"aa"出现在这个字符串中的次数,我也会得到两次.

string.count('aa')
=> 2
Run Code Online (Sandbox Code Playgroud)

我不明白这一点.我把值放在引号中,所以我在搜索确切字符串出现的次数,而不仅仅是字母.

Car*_*and 53

这里有几种方法来计算给定子字符串出现在字符串中的次数(第一个是我的偏好).注意(由OP确认)子字符串在字符串中'aa'出现两次'aaa',因此在以下情况下出现五次:

string="aaabbccaaaaddbb"
Run Code Online (Sandbox Code Playgroud)

#1

String#scan与正则表达式一起使用,该正则表达式包含查找子字符串的正向前瞻:

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

count_em(string,"aa")
 #=> 5
Run Code Online (Sandbox Code Playgroud)

注意:

"aaabbccaaaaddbb".scan(/(?=aa)/)
  #=> ["", "", "", "", ""]
Run Code Online (Sandbox Code Playgroud)

积极的lookbehind产生相同的结果:

"aaabbccaaaaddbb".scan(/(?<=aa)/)
  #=> ["", "", "", "", ""]
Run Code Online (Sandbox Code Playgroud)

同样,String#scan可以用String#gsub替换.

#2

转换为数组,应用Enumerable#each_cons,然后加入并计数:

def count_em(string, substring)
  string.each_char.each_cons(substring.size).map(&:join).count(substring)
end

count_em(string,"aa")
  #=> 5
Run Code Online (Sandbox Code Playgroud)

我们有:

enum0 = "aaabbccaaaaddbb".each_char
  #=> #<Enumerator: "aaabbccaaaaddbb":each_char>
Run Code Online (Sandbox Code Playgroud)

我们可以通过将它转换为数组来查看此枚举器生成的元素:

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)> 
Run Code Online (Sandbox Code Playgroud)

转换enum1为数组以查看枚举器将传递给的值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
Run Code Online (Sandbox Code Playgroud)


tad*_*man 27

这是因为count计数字符,而不是字符串的实例.在这种情况下'aa'意味着同样的事情'a',它被认为是一组要计算的字符.

要计算aa字符串中出现的次数:

string = "aabbccddbb"
string.scan(/aa/).length
# => 1
string.scan(/bb/).length
# => 2
string.scan(/ff/).length
# => 0
Run Code Online (Sandbox Code Playgroud)

  • 在此示例中没有理由使用Regexp而不是String. (3认同)
  • 是的[`scan`](http://www.ruby-doc.org/core-2.1.2/String.html#method-i-scan)采用像`/ aa /`这样的正则表达式,甚至像`"aa"`如果你愿意并且返回比赛.如果你不在乎比赛是什么,`length`会告诉你多少场比赛. (2认同)