2010-09-09 17 views
6

Ich möchte eine Funktion machen, die eine Zeichenkette auf Vorkommen von anderen Zeichenketten in ihnen prüft.
Die Unterzeichenfolgen, die überprüft werden, können jedoch innerhalb der Hauptsyntax durch andere Buchstaben unterbrochen werden.Finde Teilfolgen von Strings innerhalb von Strings

Zum Beispiel:

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

Die betreffende Funktion als b ist in a zurückgeben sollte, aber nicht c.

Ich habe versucht set(a). Kreuzung (set (b)) bereits, und mein Problem damit ist, dass es c als a zurückgibt.

+0

Diese Art von Zeichenketten werden als [Teilfolgen] (http: //en.wikipedia. org/wiki/Subsequence) der längeren Zeichenfolge. – Lazer

+0

Diese Frage ist ein Sonderfall von http://stackoverflow.com/questions/6877249/find-the-number-of-occurrrences-of-a-subsequence-in-a-string Die Lösungen dort sind viel effizienter zu lösen auch in diesem Fall. – Amoss

Antwort

11

Sie können Ihre erwartete Sequenz in einen regulären Ausdruck drehen:

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) 

"ace" wird in die regex gedreht ". A * c * e", die diese drei Zeichen in Folge findet, mit möglichen dazwischen Figuren.

+0

Danke für die schnelle Antwort! –

5

wie wäre es so etwas wie dieses ...

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 

oder ...

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

Ich erwarte, dass dies schneller als die Regex-basierte Antwort läuft. Hast du Timings? –

+0

Nein, keine Timings, nur als Alternative geschrieben. –

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

Erklären Sie bitte den Weißraumkommentar. –

+1

Die Frage war, Subsequenz, nicht Teilzeichenfolge zu finden – gizmo