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

例如:

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

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


当前回答

你可以用两种方法计算频率:

使用str中的count(): a.count (b) 或者,你可以用: len (a.split (b)) 1

其中a是字符串,b是要计算频率的子字符串。

其他回答

我将把我接受的答案作为“简单而明显的方法”,然而,它不包括重叠的情况。 通过多次检查切片就可以简单地找出这些问题——比如:

sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))

结果是3。

或者可以通过使用正则表达式来实现,如如何使用regex来查找所有重叠的匹配项中所示——它也可以用于良好的代码高尔夫。

这是我的“手工”计数模式重叠出现在一个字符串,它试图不是非常幼稚(至少它不会在每次交互时创建新的字符串对象):

def find_matches_overlapping(text, pattern):
    lpat = len(pattern) - 1
    matches = []
    text = array("u", text)
    pattern = array("u", pattern)
    indexes = {}
    for i in range(len(text) - lpat):
        if text[i] == pattern[0]:
            indexes[i] = -1
        for index, counter in list(indexes.items()):
            counter += 1
            if text[i] == pattern[counter]:
                if counter == lpat:
                    matches.append(index)
                    del indexes[index]
                else:
                    indexes[index] = counter
            else:
                del indexes[index]
    return matches
            
def count_matches(text, pattern):
    return len(find_matches_overlapping(text, pattern))

对于一个有空格分隔的简单字符串,使用Dict会非常快,请参阅下面的代码

def getStringCount(mnstr:str, sbstr:str='')->int:
    """ Assumes two inputs string giving the string and 
        substring to look for number of occurances 
        Returns the number of occurances of a given string
    """
    x = dict()
    x[sbstr] = 0
    sbstr = sbstr.strip()
    for st in mnstr.split(' '):
        if st not in [sbstr]:
            continue
        try:
            x[st]+=1
        except KeyError:
            x[st] = 1
    return x[sbstr]

s = 'foo bar foo test one two three foo bar'
getStringCount(s,'foo')

目前涉及方法计数的最佳答案并不能真正计算重叠出现的次数,也不关心空子字符串。 例如:

>>> a = 'caatatab'
>>> b = 'ata'
>>> print(a.count(b)) #overlapping
1
>>>print(a.count('')) #empty string
9

如果我们考虑重叠的子字符串,第一个答案应该是2而不是1。 对于第二个答案,如果空子字符串返回0作为asnwer会更好。

下面的代码处理这些事情。

def num_of_patterns(astr,pattern):
    astr, pattern = astr.strip(), pattern.strip()
    if pattern == '': return 0

    ind, count, start_flag = 0,0,0
    while True:
        try:
            if start_flag == 0:
                ind = astr.index(pattern)
                start_flag = 1
            else:
                ind += 1 + astr[ind+1:].index(pattern)
            count += 1
        except:
            break
    return count

现在当我们运行它时:

>>>num_of_patterns('caatatab', 'ata') #overlapping
2
>>>num_of_patterns('caatatab', '') #empty string
0
>>>num_of_patterns('abcdabcva','ab') #normal
2
s = 'arunununghhjj'
sb = 'nun'
results = 0
sub_len = len(sb)
for i in range(len(s)):
    if s[i:i+sub_len] == sb:
        results += 1
print results

如果你想计算所有的子字符串(包括重叠的),那么使用这个方法。

import re
def count_substring(string, sub_string):
    regex = '(?='+sub_string+')'
    # print(regex)
    return len(re.findall(regex,string))