web-dev-qa-db-fra.com

Compter le nombre d'occurrences d'une sous-chaîne donnée dans une chaîne

Comment compter le nombre de fois qu'une sous-chaîne donnée est présente dans une chaîne en Python?

Par exemple:

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

string.count(substring), comme dans:

>>> "abcdabcva".count("ab")
2

update: comme indiqué dans les commentaires, voici le moyen de le faire pour les occurrences non chevauchantes. Si vous devez compter les occurrences qui se chevauchent, vous feriez mieux de vérifier les réponses à: " Une expression rationnelle Python trouve toutes les correspondances qui se chevauchent? ", ou tout simplement de vérifier mon autre réponse ci-dessous.

271
jsbueno

En fonction de ce que vous voulez vraiment dire, je propose les solutions suivantes:

1) Vous voulez dire une liste de sous-chaînes séparées par un espace et vous voulez savoir quel est le numéro de position de sous-chaîne parmi toutes les sous-chaînes:

s = 'sub1 sub2 sub3'
s.split().index('sub2')
>>> 1

2) Vous voulez dire le caractère de la sous-chaîne dans la chaîne:

s.find('sub2')
>>> 5

3) Vous voulez dire les (non-chevauchements) comptes d’apparence d’un sous-chaîne:

s.count('sub2')
>>> 1
s.count('sub')
>>> 3
17
Don Question
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
15
Arun Kumar Khattri

Pour rechercher les occurrences de sous-chaînes qui se chevauchent dans une chaîne dans Python 3, cet algorithme fera:

def count_substring(string,sub_string):
    l=len(sub_string)
    count=0
    for i in range(len(string)-len(sub_string)+1):
        if(string[i:i+len(sub_string)] == sub_string ):      
            count+=1
    return count  

J'ai moi-même vérifié cet algorithme et cela a fonctionné.

9
Bharath Kumar R

Le meilleur moyen de rechercher une sous-chaîne qui se chevauche dans une chaîne donnée est d'utiliser l'expression régulière python, qui recherchera toutes les correspondances qui se chevauchent à l'aide de la bibliothèque d'expressions régulières. Voici comment le faire. Il reste la sous-chaîne à gauche et, à droite, vous fournissez la chaîne à associer.

print len(re.findall('(?=aa)','caaaab'))
3
9
Deepak Yadav

La meilleure réponse actuelle avec la méthode count ne compte pas vraiment pour les occurrences qui se chevauchent et ne se soucie pas non plus des sous-chaînes vides . Par exemple:

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

La première réponse devrait être 2 pas 1, si on considère les sous-chaînes qui se chevauchent . Quant à la deuxième réponse, il est préférable qu'une sous-chaîne vide retourne 0 comme asnwer.

Le code suivant prend en charge ces choses.

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

Maintenant quand on le lance:

>>>num_of_patterns('caatatab', 'ata') #overlapping
2
>>>num_of_patterns('caatatab', '') #empty string
0
>>>num_of_patterns('abcdabcva','ab') #normal
2
6
Nuhman

La question n'est pas très claire, mais je vais répondre à ce que vous demandez en apparence.

Une chaîne S, longue de L caractères, et où S [1] est le premier caractère de la chaîne et S [L], le dernier caractère, contient les sous-chaînes suivantes:

  • La chaîne nulle ''. Il y en a un. 
  • Pour chaque valeur A de 1 à L, pour chaque valeur B de A à L, la chaîne S [A] .. S [B] (Inclus). Il y a L + L-1 + L-2 + ... 1 de ces chaînes, pour un total de 0.5 * L * (L + 1). 
  • Notez que le deuxième élément comprend S [1] .. S [L], la chaîne originale entière S.

Donc, il y a 0,5 * L * (L + 1) + 1 sous-chaînes dans une chaîne de longueur L. Rendez cette expression en Python et vous avez le nombre de sous-chaînes présentes dans la chaîne. 

4
Jim DeLaHunt

Une solution consiste à utiliser re.subn . Par exemple, pour compter le nombre d'occurrences De 'hello' dans n'importe quelle combinaison de cas, vous pouvez effectuer les tâches suivantes:

import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of "hello"')
4
Eugene Yarmash

Je garderai ma réponse acceptée comme étant "le moyen simple et évident de le faire" - cependant, cela ne couvre pas les cas de chevauchement. Il est possible de les rechercher naïvement, en vérifiant plusieurs fois les tranches - comme dans: sum ("GCAAAAAGH" [i:]. commence avec (AAA ") pour i dans la plage (len (" GCAAAAAGH ")))

(qui donne 3) - cela peut être fait en utilisant des expressions régulières, comme on peut le voir sur Les expressions rationnelles Python trouvent toutes les correspondances qui se chevauchent? - et cela peut aussi permettre de jouer au code fin- C'est mon compte "fait main" pour le chevauchement des motifs de motifs dans une chaîne qui tente de ne pas être extrêmement naïf interaction):

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))
2
jsbueno

Pour les comptes qui se chevauchent, nous pouvons utiliser:

def count_substring(string, sub_string):
    count=0
    beg=0
    while(string.find(sub_string,beg)!=-1) :
        count=count+1
        beg=string.find(sub_string,beg)
        beg=beg+1
    return count

Pour les cas ne se chevauchant pas, nous pouvons utiliser la fonction count ():

string.count(sub_string)
2
Dhiraj Dwivedi

Occurrences se chevauchant:

def olpcount(string,pattern,case_sensitive=True):
    if case_sensitive != True:
        string  = string.lower()
        pattern = pattern.lower()
    l = len(pattern)
    ct = 0
    for c in range(0,len(string)):
        if string[c:c+l] == pattern:
            ct += 1
    return ct

test = 'my maaather lies over the oceaaan'
print test
print olpcount(test,'a')
print olpcount(test,'aa')
print olpcount(test,'aaa')

Résultats:

my maaather lies over the oceaaan
6
4
2
2
fyngyrz

Que diriez-vous d'un one-liner avec une liste de compréhension? Techniquement, ses 93 caractères m'épargnent le purisme PEP-8. La réponse regex.findall est la plus lisible si c'est un morceau de code de haut niveau. Si vous construisez quelque chose de bas niveau et que vous ne voulez pas de dépendances, celle-ci est plutôt maigre et moyenne. Je donne la réponse qui se chevauchent. Évidemment, il suffit d'utiliser un nombre comme la réponse la plus élevée s'il n'y a pas de chevauchement.

def count_substring(string, sub_string):
    return len([i for i in range(len(string)) if string[i:i+len(sub_string)] == sub_string])
1
Ryan Dines

Scénario 1: Occurrence d'un mot dans une phrase . Exemple: str1 = "This is an example and is easy". L'occurrence de la Parole "est". laisse str2 = "is"

count = str1.count(str2)

Scénario 2: occurrence d'un motif dans une phrase.

string = "ABCDCDC"
substring = "CDC"

def count_substring(string,sub_string):
len1 = len(string)
len2 = len(sub_string)
j =0
counter = 0
while(j < len1):
    if(string[j] == sub_string[0]):
        if(string[j:j+len2] == sub_string):
            counter += 1
    j += 1

return counter

Merci!

1
Amith V V

Si vous voulez connaître le nombre de sous-chaînes à l'intérieur d'une chaîne, S'il vous plaît utiliser le code ci-dessous . Le code est facile à comprendre c'est pourquoi j'ai ignoré les commentaires. :)

string=raw_input()
sub_string=raw_input()
start=0
answer=0
length=len(string)
index=string.find(sub_string,start,length)
while index<>-1:
    start=index+1
    answer=answer+1
    index=string.find(sub_string,start,length)
print answer
1
Hemant
s = input('enter the main string: ')
p=input('enter the substring: ')
l=[]
for i in range(len(s)):
    l.append(s[i:i+len(p)])
print(l.count(p))
0
pawan kumar

Voici la solution dans Python 3 et en respectant la casse:

s = 'foo bar foo'.upper()
sb = 'foo'.upper()
results = 0
sub_len = len(sb)
for i in range(len(s)):
    if s[i:i+sub_len] == sb:
        results += 1
print(results)
0
attachPost

Si vous souhaitez compter toutes les sous-chaînes (y compris les chevauchements), utilisez cette méthode.

import re
def count_substring(string, sub_string):
    regex = '(?='+sub_string+')'
    # print(regex)
    return len(re.findall(regex,string))
0
Rahul Verma
import re
d = [m.start() for m in re.finditer(seaching, string)] 
print (d)

Ceci trouve le nombre de fois que la sous-chaîne a été trouvée dans la chaîne et affiche l'index.

0
Bhaskar Reddi K
my_string = """Strings are amongst the most popular data types in Python. 
               We can create the strings by enclosing characters in quotes.
               Python treats single quotes the same as double quotes."""

Count = my_string.lower().strip("\n").split(" ").count("string")
Count = my_string.lower().strip("\n").split(" ").count("strings")
print("The number of occurance of Word String is : " , Count)
print("The number of occurance of Word Strings is : " , Count)
0
Vinay Kumar Kuresi

La logique ci-dessous fonctionnera pour toutes les chaînes et les caractères spéciaux

def cnt_substr(inp_str, sub_str):

    inp_join_str = ''.join(inp_str.split())

    sub_join_str = ''.join(sub_str.split())

    return inp_join_str.count(sub_join_str)

print(cnt_substr("the sky is   $blue and not greenthe sky is   $blue and not green", "the sky"))
0
skay
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
0
vengat
string="abc"
mainstr="ncnabckjdjkabcxcxccccxcxcabc"
count=0
for i in range(0,len(mainstr)):
    k=0
    while(k<len(string)):
        if(string[k]==mainstr[i+k]):
            k+=1
        else:
            break   
    if(k==len(string)):
        count+=1;   
print(count)
0
kamran shaik
#counting occurence of a substring in another string (overlapping/non overlapping)
s = input('enter the main string: ')# e.g. 'bobazcbobobegbobobgbobobhaklpbobawanbobobobob'
p=input('enter the substring: ')# e.g. 'bob'

counter=0
c=0

for i in range(len(s)-len(p)+1):
    for j in range(len(p)):
        if s[i+j]==p[j]:
            if c<len(p):
                c=c+1
                if c==len(p):
                    counter+=1
                    c=0
                    break
                continue
        else:
            break
print('number of occurences of the substring in the main string is: ',counter)
0
pawan kumar

Pour une chaîne simple avec une délimitation d'espace, utiliser Dict serait assez rapide, veuillez consulter le code ci-dessous

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')
0
Amit Gowda

Vous pouvez utiliser la fonction startwith

def count_substring(string, sub_string):
x = 0
for i in range(len(string)):
    if string[i:].startswith(sub_string):
        x += 1
return x

trouver des informations sur startswith () ici https://www.tutorialspoint.com/python/string_startswith.htm

0
Trevor Maseleme

Je ne suis pas sûr qu'il s'agisse de quelque chose qui a déjà été examiné, mais j'ai pensé à cela comme une solution pour un mot "jetable":

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

print count

Word est le mot que vous recherchez et terme est le terme que vous recherchez

0
Alan Vinton

Risquer un vote négatif parce que 2+ autres ont déjà fourni cette solution. J'ai même voté l'un d'eux. Mais le mien est probablement le plus facile à comprendre pour les débutants.

def count_substring(string, sub_string):
    slen  = len(string)
    sslen = len(sub_string)
    range_s = slen - sslen + 1
    count = 0
    for i in range(range_s):
        if (string[i:i+sslen] == sub_string):
            count += 1
    return count
0
BabarBaig