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

时间:2022-10-14 15:42:51

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:

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

string = "aabbccddbb"
string.count('a')
=> 2

But if I search for how many times 'aa' appears in this string, I also get two.

但是,如果我搜索“aa”出现在该字符串中的次数,我也会得到两次。

string.count('aa')
=> 2

I don't understand this. I put the value in quotation marks, so I'm searching for the number of times the exact string appears, not just the letters.

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

2 个解决方案

#1


33  

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:

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

string="aaabbccaaaaddbb"

#1

#1

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

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

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:

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

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

#2

#2

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

转换为数组,应用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

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转换为数组以查看枚举器将传递给映射的值:

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

#2


16  

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.

这是因为计数计数字符,而不是字符串的实例。在这种情况下,'aa'与'a'意思相同,它被认为是一组要计算的字符。

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

#1


33  

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:

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

string="aaabbccaaaaddbb"

#1

#1

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

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

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:

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

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

#2

#2

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

转换为数组,应用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

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转换为数组以查看枚举器将传递给映射的值:

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

#2


16  

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.

这是因为计数计数字符,而不是字符串的实例。在这种情况下,'aa'与'a'意思相同,它被认为是一组要计算的字符。

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