2016-08-01 6 views
1

Ich habe eine Liste der möglichen Trennzeichen. Ich verarbeite einige tausend Zeichenfolgen und muss alles entfernen, nachdem eines der Trennzeichen gefunden wurde. Hinweis: Es wird nie einen Fall geben, wenn mehr als 1 Trennzeichen in der Zeichenfolge enthalten ist.Strip alles nach der Liste der möglichen Trennzeichen ohne Regex

Beispiel:

patterns = ['abc', 'def'] 
example_string = 'hello world abc 123' 

example_string Wenn der Eingang ist in diesem Fall, sollte der Ausgang hello world abc sein.

Ich benutze derzeit Regex für die Lösung, die funktioniert, aber ich möchte einen Ansatz verwenden, der Regex nicht verwendet. Hier ist meine aktuelle Implementierung:

regex = r'(.*)(' + '|'.join(patterns) + r')(.*)' 
example_string= re.sub(regex, r'\1\2', example_string).lstrip() 

ich etwas entlang der Linien des Suchens denke, um zu sehen, wenn eine der Begrenzungszeichen von Mustern in der Zeichenfolge ist und dann die Indizierung die Zeichenfolge aus der Position der Länge des Trennzeichens, bis die Ende der Zeichenfolge.

Ich weiß nicht genau, ob das ein guter Weg wäre, das zu implementieren, oder ob das funktionieren würde.

+0

Ungefähr wie viele Zeichenfolgen sind in "Mustern"? Sind sie alle gleich lang? –

+0

Es gibt 28 Zeichenfolgen in Mustern, die sich jedoch im Laufe der Zeit ändern können. Und nein, die Längen der Saiten variieren. – Harrison

+0

In diesem Fall wird Ihr Regex-basierter Ansatz wahrscheinlich besser sein als jede Nicht-Regex-Lösung. –

Antwort

3

Sie könnten die find Funktion verwenden. Hier wird jedes Muster wird überprüft und festgestellt, wenn die Zeichenfolge an der Startposition des Musters in Scheiben geschnitten (oder der Endstelle des Musters durch die Länge des Musters hinzugefügt, wie im Beispiel):

patterns = ['abc', 'def'] 
    example_string = 'hello world abc 123' 
    for pattern in patterns: 
     location = example_string.find(pattern) 
     if location >= 0: 
      example_string = example_string[:location + len(pattern)] 
      print example_string 
      break 
2

mit dem finden Methode

string.find (s, sub [, Start [End]])

Return dem niedrigsten Index in s, wo die Teilunter solche gefunden wird, dass die vollständig in Unter s enthalten ist [Start Ende]. Rückgabe -1 bei Fehler. Die Standardwerte für Anfang und Ende und die Interpretation negativer Werte sind die gleichen wie für Slices.

und Ihr Ergebnis ist s [: Ende]

3

Sie Liste Verständnis und Slicing missbrauchen:

delimiters = ['a', 'b'] 
s = 'nvcakl' 
s = [s[:s.index(i) + 1] for i in delimiters if i in s] 
print(s) 
>> ['nvca'] 

Dies funktioniert sogar, wenn mehr als ein Trennzeichen gefunden wird, jeder Index in der Ausgabeliste entspricht dem gefundenen Trennzeichen, zB:

delimiters = ['a', 'b'] 
s = 'nvcaklbh' 
s = [s[:s.index(i) + 1] for i in delimiters if i in s] 
print(s) 
>> ['nvca', 'nvcaklb'] 
+0

Wenn durch irgendeine freak Chance, dass es mehr als 1 Trennzeichen gefunden wird, möchte ich, dass die Zeichenfolge beim ersten Auftreten eines Trennzeichens entfernt wird. Wäre das immer noch eine ideale Lösung? – Harrison

+0

Die Trennzeichen des OPs sind Strings unterschiedlicher Länge, so dass '+ 1' im Allgemeinen nicht funktioniert.Außerdem testet dieser Algorithmus alle Begrenzer, selbst nachdem eine Übereinstimmung gefunden wurde. –

+0

@ PM2Ring Dies ist eine grobe Idee, es ist kein Problem, '+ 1' zu' + len (i) ' – DeepSpace

Verwandte Themen