Suche in Zeichenketten

Wir können nun eine Funktion schreiben, die zählt, wie oft ein gegebenes Zeichen in einer Zeichenkette vorkommt:

def count_char(text, char):
  count = 0
  for index in range(0, len(text)):  # len(x) liefert die Länge des Textes x
    if text[index] == char:
      count = count + 1
  return count

Hierzu durchlaufen wir in einer Zählschleife alle Zeichen der Zeichenkette text und erhöhen den Zähler count, wenn wir das gesuchte Zeichen char finden. Die Zahlvariable index durchläuft die Indizes dabei mit 0 beginnend.

Hier sind einige Beispielaufrufe:

>>> count_char('Hallo Welt!','l')
3
>>> count_char('Hallo Welt!','!')
1
>>> count_char('Hallo Welt!','x')
0

Wenn wir nur daran interessiert sind, ob das Zeichen enthalten ist, aber nicht daran wie oft, können wir stattdessen eine bedingte Schleife verwenden, um die Suche bei Erfolg vorzeitig zu beenden:

def has_char(text, char):
  found = False
  index = 0
  while not found and index < len(text):
    found = text[index] == char
    index = index + 1
  return found    

Wir verzichten hier auf eine bedingte Anweisung in Schleifenrumpf, da die Schleife im Fall found == True abbricht, die Variable found also später keine anderen Werte mehr zugewiesen bekommt.

Das aktuelle Zeichen selektieren wir dabei wieder anhand einer Zählvariable index.

Diese Funktion können wir wie folgt verwenden:

>>> has_char('Hallo Welt!', 'l') 
True 
>>> has_char('Hallo Welt!', '!') 
True 
>>> has_char('Hallo Welt!', 'x') 
False

Wir können auf diese Weise auch nach Teilstrings beliebiger Länge suchen und müssen dazu nur die selektierte Länge an den gesuchten String anpassen:

def has_string(text, string):
  found = False
  index = 0
  while not found and index < len(text):
    found = text[index:(index + len(string))] == string
    index = index + 1
  return found   

Zur Illustration wieder einige Beispiele:

>>> has_string('Hallo Welt!', 'llo')
True
>>> has_string('Hallo Welt!', 'lol')
False
>>> has_string('Hallo Welt!', 'welt')
False

Es wird also Groß- und Kleinschreibung unterschieden.

Schließlich können wir dieses Programm noch so abwandeln, dass es den ersten Index zurück gibt, an dem der gesuchte String gefunden wurde (bzw. den Fehlerwert None, falls er nicht gefunden wird).1

def index_of(text, string):
  found = False
  index = 0
  while not found and index < len(text):
    found = text[index:(index + len(string))] == string
    index = index + 1
  if found:
    return (index - 1)
  else:
    return None

Hierbei erniedrigen wir den Wert von index, bevor wir ihn zurückliefern, da er bei erfolgreicher Suche am Ende des Schleifenrumpfes einmal zu oft erhöht wird. Wieder ein paar Beispielaufrufe zur Illustration:

>>> index_of('Hallo Welt!', 'Hallo')
0
>>> index_of('Hallo Welt!', 'Welt')
6
>>> index_of('Hallo Welt!', 'welt')

Das Ergebnis None des letzten Aufrufs wird in der interaktiven Python-Umgebung nicht angezeigt.

Mit der vordefinierten Funktion open() können wir den Inhalt von Textdateien einlesen. Dabei erhalten wir ein File-Objekt, das wir mit read() in eine Zeichenkette umwandeln können. Dies ermöglicht es uns, auch in größeren Texten, zum Beispiel in unserem Programm, nach Zeichenketten zu suchen.

>>> source = open('strings.py').read()
>>> indexOf(source,"def has_string")
365

  1. Der Wert None wird in Python dort verwendet, wo kein sinnvoller Wert möglich ist. Viele Programiersprachen stellen ähnliche Werte bereit, die dort z.B. null oder nil heißen. ↩︎