klausschreiber
Well-known member
- 6 Mai 2006
- 247
- 8
Hallo,
ich möchte einen Text am Satzende trennen bzw. in ein Array umwandeln. Normalerweise könnte man da ja einfach den Punkt, das Fragezeichen und das Ausrufezeichen hernehmen. Problematisch sind jedoch Abkürzungen, sowie so Sachen wie 14. Mai usw.
Beispieltext:
ich möchte einen Text am Satzende trennen bzw. in ein Array umwandeln. Normalerweise könnte man da ja einfach den Punkt, das Fragezeichen und das Ausrufezeichen hernehmen. Problematisch sind jedoch Abkürzungen, sowie so Sachen wie 14. Mai usw.
Beispieltext:
Das ist ein Test. Ich mache hier viele Testz. z.B. gibt es hier viele Sachen, über die ich z.B. schreiben könnte. Heute haben wir den 14. Mai. Ist das wirklich wahr? Ich glaube schon! Der Preis beträgt 19 Euro inkl. Mwst. und sonstigen Kosten./QUOTE]
Optimales Ergebnis:
PHP:satzteil[0] = "Das ist ein Test." satzteil[1] = "Ich mache hier viele Testz." satzteil[2] = "z.B. gibt es hier viele Sachen, über die ich z.B. schreiben könnte." satzteil[3] = "Heute haben wir den 14. Mai." satzteil[4] = "Ist das wirklich wahr?" satzteil[5] = "Ich glaube schon!" satzteil[6] = "Der Preis beträgt 19 Euro inkl. Mwst. und sonstigen Kosten."
Theoretisch würde es mit preg_split und lookbehinds funktionieren:
Das Problem ist, dass in lookbehinds manche Dinge nicht funktionieren. Ich schaue immer, ob vor der Abkürzung ein Leerzeichen ist, damit nicht fälschlicherweise ein Wort als Abkürzung erkannt wird. (Nehmen wir an, "tz." ist eine Abkürzung, dann soll in "Ich schreibe einen Satz." das "tz." trotzdem nicht als Abkürzung erkannt werden.PHP:$pattern = '~(\!|\?|(?<! z| z\.b| inkl| mwst|[0-9])\.)~is'; $satzteil = preg_split($pattern, $text, -1, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE);
Der beste regex innerhalb des lookbehinds wäre " (z|z\.b|inkl|mwst|[0-9]+)" (Leerzeichen am Anfang). Aber sowohl "x(ab|cde)" also auch "[0-9]+" Konstruktionen sind ja im lookbehind nicht erlaubt.
Meine Lösung ist ja " z| z\.b| inkl| mwst|[0-9]", also vor jeder Abkürzung ein Leerzeichen, vor Zahlen jedoch nicht, weil eine Zahl ja auch aus mehr als einer Ziffer bestehen kann.
Es funktioniert zwar, aber optimal ist es irgendwie nicht.
Zweiter Versuch war mit preg_match_all und "[^.?!]+( (z\.B\.)|(inkl\.)|[0-9]+)*\.". Leider interpretiert er da die Abkürzungen da trotzdem als Satzende.
Gibt es irgendwie eine bessere Lösung, als ich sie mit preg_split habe?
Was ich mir sonst noch überlegt habe, wäre alle Wörter mit einem Punkt rauszufiltern, dann in einem Array oder einer Datenbank zu schauen, ob es eine Abkürzung ist und falls nicht, das Leerzeichen nach dem Punkt durch ein "new line" auszutauschen perund danach dann halt per explode zu trennen.PHP:string[x] = "\n";
Da es ja vermutlich recht viele gängige deutsche Abkürzungen gibt, die einen Punkt enthalten, ist es überhaupt sinnvoll, das per regex (ab|cd|ef) zu machen oder ist eine Suche in der Datenbank da sowieso schneller?
Danke und Gruß,
Klaus