Finde viel String im Text – Python

Ich suche nach dem besten Algorithmus, um dieses Problem zu lösen: Mit einer Liste (oder einem Diktat, einem Satz) von kleinen Sätzen, finden Sie alle Vorkommen dieser Sätze in einem größeren Text. Die Sätze in der Liste (oder dict, oder set) sind etwa 600k, aber im Durchschnitt um 3 Wörter gebildet. Der Text ist durchschnittlich 25 Wörter lang. Ich habe gerade den Text formatiert (Interpunktion löschen, ganz Kleinbuchstaben und so weitergehen).

Hier ist was ich ausprobiert habe (Python):

to_find_sentences = [ 'bla bla', 'have a tea', 'hy im luca', 'i love android', 'i love ios', ..... ] text = 'i love android and i think i will have a tea with john' def find_sentence(to_find_sentences, text): text = text.split() res = [] w = len(text) for i in range(w): for j in range(i+1,w+1): tmp = ' '.join(descr[i:j]) if tmp in to_find_sentences: res.add(tmp) return res print find_sentence(to_find_sentence, text) 

Aus:

 ['i love android', 'have a tea'] 

In meinem Fall habe ich einen Satz benutzt, um den Betrieb zu beschleunigen

One Solution collect form web for “Finde viel String im Text – Python”

Eine schnelle Lösung wäre, einen Trie aus deinen Sätzen zu bauen und diesen Trie in einen Regex umzuwandeln. Für Ihr Beispiel würde das Muster so aussehen:

 (?:bla\ bla|h(?:ave\ a\ tea|y\ i\ m\ luca)|i\ love\ (?:android|ios)) 

Hier ist ein Beispiel für Debuggex :

Bildbeschreibung hier eingeben

Es könnte eine gute Idee sein, '\b' als Wortgrenzen hinzuzufügen, um zu vermeiden, dass "have a team" .

Du brauchst ein kleines Trie-Skript . Es ist noch kein offizielles Paket, aber du kannst es einfach hier als trie.py in deinem aktuellen Verzeichnis herunterladen.

Sie können diesen Code dann verwenden, um die Trie / Regex zu erzeugen:

 import re from trie import Trie to_find_sentences = [ 'bla bla', 'have a tea', 'hy im luca', 'i love android', 'i love ios', ] trie = Trie() for sentence in to_find_sentences: trie.add(sentence) print(trie.pattern()) # (?:bla\ bla|h(?:ave\ a\ tea|y\ i\ m\ luca)|i\ love\ (?:android|ios)) pattern = re.compile(r"\b" + trie.pattern() + r"\b", re.IGNORECASE) text = 'i love android and i think i will have a tea with john' print(re.findall(pattern, text)) # ['i love android', 'have a tea'] 

Sie investieren einige Zeit, um die Trie und die Regex zu erstellen, aber die Verarbeitung sollte extrem schnell sein.

Hier ist eine verwandte Antwort (beschleunigen Millionen von Regex-Ersatz in Python 3), wenn Sie mehr Informationen wünschen.

Beachten Sie, dass es keine überlappenden Sätze findet:

 to_find_sentences = [ 'i love android', 'android Marshmallow' ] # ... print(re.findall(pattern, "I love android Marshmallow")) # ['I love android'] 

Du musst den Regex mit positiven Lookaheads modifizieren, um überlappende Sätze zu finden.

  • Sollte ich vermeiden, in einen String zu konvertieren, wenn ein Wert bereits ein String ist?
  • Python: Split-String mit mehreren Trennzeichen [doppelte]
  • Finden Sie den entsprechenden Wert für ein Keyword in der Datei mit Python
  • ABC für String?
  • Python entkommt Sonderzeichen in sys argv
  • Konvertieren Sie Datei in HEX String Python
  • Int-Umwandlung funktioniert nicht [doppelt]
  • Finde den Index des letzten Vorkommens eines Teilstrings in einer Zeichenfolge
  • Löschen Sie mehrere Zeilen in MYSQL mit Info aus der Python-Liste
  • So ändern Sie einen String in Großbuchstaben
  • Wie bekomme ich ein Pfadpräfix in Python?
  • Python ist die beste Programmiersprache der Welt.