2010-09-09 23 views
6

Quiero hacer una función que compruebe una cadena para ver si hay otras cadenas dentro de ellas.
Sin embargo, las subcadenas que se están verificando pueden interrumpirse dentro de la cadena principal por otras letras.Buscar subsecuencias de cadenas dentro de cadenas

Por ejemplo:

a = 'abcde' 
b = 'ace' 
c = 'acb' 

La función en cuestión debe devolver como b estar en a, pero no c.

He intentado set(a). intersection (set (b)) ya, y mi problema con eso es que devuelve c como en a.

+0

Este tipo de cadenas se denominan [subsecuencias] (http: //en.wikipedia. org/wiki/Subsequence) de la cadena más larga. – Lazer

+0

Esta pregunta es un caso especial de http://stackoverflow.com/questions/6877249/find-the-number-of-occurrences-of-a-subsequence-in-a-string Las soluciones allí son mucho más eficientes para resolver este caso también – Amoss

Respuesta

11

puede convertir su secuencia esperada en una expresión regular:

import re 

def sequence_in(s1, s2): 
    """Does `s1` appear in sequence in `s2`?""" 
    pat = ".*".join(s1) 
    if re.search(pat, s2): 
     return True 
    return False 

# or, more compactly: 
def sequence_in(s1, s2): 
    """Does `s1` appear in sequence in `s2`?""" 
    return bool(re.search(".*".join(s1), s2)) 

a = 'abcde' 
b = 'ace' 
c = 'acb' 

assert sequence_in(b, a) 
assert not sequence_in(c, a) 

"as" se convirtió en la expresión regular ". A * c * e", que encuentra esos tres caracteres en secuencia, con la intervención posible caracteres.

+0

¡Gracias por la pronta respuesta! –

5

¿qué tal algo como esto ...

def issubstr(substr, mystr, start_index=0): 
    try: 
     for letter in substr: 
      start_index = mystr.index(letter, start_index) + 1 
     return True 
    except: return False 

o ...

def issubstr(substr, mystr, start_index=0): 
    for letter in substr: 
     start_index = mystr.find(letter, start_index) + 1 
     if start_index == 0: return False 
    return True 
+0

Espero que esto se ejecute más rápido que la respuesta basada en expresiones regulares. ¿Tienes horarios? –

+0

No hay horarios, simplemente lo escribió como una alternativa. –

3
def issubstr(s1, s2): 
    return "".join(x for x in s2 if x in s1) == s1 

>>> issubstr('ace', 'abcde') 
True 

>>> issubstr('acb', 'abcde') 
False 
+0

Explica el comentario de espacio en blanco por favor. –

+1

La pregunta era encontrar subsecuencia, no subcadena – gizmo

Cuestiones relacionadas