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.

  • Standard-Weg zur Einbettung Version in Python-Paket?
  • Wie schreibe ich String-Literale in Python, ohne ihnen zu entkommen?
  • In Python 2 kann ich eine Liste an den Prozentsatz-Operator übergeben?
  • Wie kann ich auf eine Instanz einer Klasse mit einem String verweisen?
  • So entfernen Sie alle Integer-Werte aus einer Liste in Python
  • Mit Backslash in Python (nicht zu entkommen)
  • Wie man die Buchstaben in einer Zeichenkette alphabetisch in Python sortiert
  • Int-Umwandlung funktioniert nicht [doppelt]
  • Wie finde ich Kleinbuchstaben in Python?
  • Was ist falsch in den Code geschrieben inpython [duplicate]
  • Transformieren Sie URL-String in normale Zeichenfolge in Python (% 20 zu Platz usw.)
  • Python ist die beste Programmiersprache der Welt.