如何计算给定子字符串在Python字符串中出现的次数?

例如:

>>> 'foo bar foo'.numberOfOccurrences('foo')
2

若要获取子字符串的索引,请参见如何查找子字符串的所有出现?。


当前回答

j = 0
    while i < len(string):
        sub_string_out = string[i:len(sub_string)+j]
        if sub_string == sub_string_out:
            count += 1
        i += 1
        j += 1
    return count

其他回答

这里有一个解决方案,适用于非重叠和重叠的情况。为了澄清:重叠子字符串是指其最后一个字符与其第一个字符相同的子字符串。

def substr_count(st, sub):
    # If a non-overlapping substring then just
    # use the standard string `count` method
    # to count the substring occurences
    if sub[0] != sub[-1]:
        return st.count(sub)

    # Otherwise, create a copy of the source string,
    # and starting from the index of the first occurence
    # of the substring, adjust the source string to start
    # from subsequent occurences of the substring and keep
    # keep count of these occurences
    _st = st[::]
    start = _st.index(sub)
    cnt = 0

    while start is not None:
        cnt += 1
        try:
            _st = _st[start + len(sub) - 1:]
            start = _st.index(sub)
        except (ValueError, IndexError):
            return cnt

    return cnt

使用Python 3.8中引入的赋值操作符,我们可以编写一个简短的函数,在循环中使用str.find()来查找字符串中目标子字符串的重叠实例。已经有一些其他的解决方案使用相同的方法,但这个更短,更快。

赋值表达式不仅用于在last-found实例之后的字符处开始下一个查找操作,还为while循环提供了终端表达式。Str.find()如果没有找到子字符串,则返回-1,在此基础上加上1将得到0,这是false,因此在没有找到更多匹配时退出循环。

# count overlapping occurrences of a substring in a string
def count_overlapping(haystack, needle, start=0, count=0):
    while start := haystack.find(needle, start) + 1:
        count += 1
    return count

print(count_overlapping("moomoooo", "oo"))    # 4

为了进一步优化性能,我们可以查阅草堆。在循环外找到一次,并将其存储在一个局部变量中。这将是更快时,有超过一对夫妇的比赛。

# count overlapping occurrences of a substring in a string
def count_overlapping(haystack, needle, start=0, count=0):
    haystack_find = haystack.find
    while start := haystack_find(needle, start) + 1:
        count += 1
    return count

这将列出字符串中所有出现的(也是重叠的)并对它们进行计数

def num_occ(str1, str2):
    l1, l2 = len(str1), len(str2)
    return len([str1[i:i + l2] for i in range(l1 - l2 + 1) if str1[i:i + l2] == str2])

例子:

str1 ='abcabcd'
str2 = 'bc'

将创建这个列表,但只保存BOLD值:

[ab, bc, ca, ab, bc, cd]

返回:

len([bc, bc])
import re
d = [m.start() for m in re.finditer(pattern, string)] 
print(d)

这将查找子字符串在字符串中被找到的次数并显示索引。

我不确定这是否已经被研究过了,但我认为这是一个“一次性”单词的解决方案:

for i in xrange(len(word)):
if word[:len(term)] == term:
    count += 1
word = word[1:]

print count

单词是你要搜索的词,术语是你要找的词