Número de apariciones de una subcadena en una cadena

Necesito contar el número de veces que la subcadena 'bob' ocurre en una cadena.

Problema de ejemplo: encuentre el número de veces que ‘bob’ ocurre en la cadena s tal que

 "s = xyzbobxyzbobxyzbob" #(here there are three occurrences) 

Aquí está mi código:

 s = "xyzbobxyzbobxyzbob" numBobs = 0 while(s.find('bob') >= 0) numBobs = numBobs + 1 print numBobs 

Dado que se supone que la función de búsqueda en Python devuelve -1 si una subcadena no está fundada, el bucle while debería finalizar después de imprimir el número incrementado de bobs cada vez que encuentra la subcadena.

Sin embargo, el progtwig resulta ser un bucle infinito cuando lo ejecuto.

    Cuando haces una s.find('bob') que buscas desde el principio, por lo que terminas encontrando la misma bob una y otra vez, necesitas cambiar tu posición de búsqueda para terminar la bobina que encontraste.

    string.find toma un argumento de inicio que puede pasar para decirle desde dónde comenzar la búsqueda, string.find también devuelve la posición en la que encontró bob, así que puede usar eso, agregarle una longitud de bob y pasarlo a la siguiente s.find .

    Por lo tanto, al inicio del ciclo, establezca start=0 cuando desee buscar desde el inicio, dentro del ciclo si find devuelve un número no negativo, debe agregarle la longitud de la cadena de búsqueda para obtener un nuevo inicio:

     srch = 'bob' start = numBobs = 0 while start >= 0: pos = s.find(srch, start) if pos < 0: break numBobs += 1 start = pos + len(srch) 

    Aquí estoy asumiendo que la cadena de búsqueda superpuesta no se considera

    Para este trabajo, str.find no es muy eficiente. En su lugar, str.count debería ser lo que usas:

     >>> s = 'xyzbobxyzbobxyzbob' >>> s.count('bob') 3 >>> s.count('xy') 3 >>> s.count('bobxyz') 2 >>> 

    O bien, si desea que se produzcan superposiciones, puede usar Regex:

     >>> from re import findall >>> s = 'bobobob' >>> len(findall('(?=bob)', s)) 3 >>> s = "bobob" >>> len(findall('(?=bob)', s)) 2 >>> 

    find no recuerda dónde estaba el partido anterior y comienza desde allí, no a menos que se lo digas. Debe realizar un seguimiento de la ubicación del partido y pasar el parámetro de start opcional. Si no lo find solo encontrarás el primer bob una y otra vez.

     find(...) S.find(sub [,start [,end]]) -> int Return the lowest index in S where substring sub is found, such that sub is contained within s[start:end]. Optional arguments start and end are interpreted as in slice notation. Return -1 on failure. 

    Aquí hay una solución que devuelve el número de sub-cadenas superpuestas sin usar Regex: (Nota: el ‘while’ loop se escribe aquí suponiendo que está buscando una subcadena de 3 caracteres, es decir, ‘bob’)

     bobs = 0 start = 0 end = 3 while end <= len(s) + 1 and start < len(s)-2 : if s.count('bob', start,end) == 1: bobs += 1 start += 1 end += 1 print(bobs) 

    Aquí tienes una función fácil para la tarea:

     def countBob(s): number=0 while s.find('Bob')>0: s=s.replace('Bob','',1) number=number+1 return number 

    Luego, le preguntas a countBob cuando lo necesites:

     countBob('This Bob runs faster than the other Bob dude!') 
     def count_substring(string, sub_string): count=a=0 while True: a=string.find(sub_string) string=string[a+1:] if a>=0: count=count+1; else: break return count