Gefällt dir dieser Artikel?

Java Regex: Strings splitten nach Zeichen und Kontext

erschienen in der Kategorie Software, am 10.02.2013
Schnatterente
Will man in Java einen String anhand eines bestimmten Zeichens in ein Array von Substrings zerlegen, kann man die split(regex) Funktion verwenden. Ein kleines Beispiel:
String str = "Rot; Blau; Grün";
String[] split = str.split(";");

Das Array split würde nun die drei Strings "Rot", "Blau" und "Grün" enthalten.

Bis hier hin ist das so schön wie unspektakulär. Heute bekam ich Post von meinem Blogleser Thomas. Er steht vor dem Problem, dass er eine Text-Datei einlesen will, in der verschiedene Einträge, ebenfalls durch Semikolons getrennt, enthalten sind. Allerdings bietet sein Dateiformat auch noch die Möglichkeit, dass Semikolons innerhalb eines Eintrags verwendet werden können (das Semikolon ist somit einerseits ein Trennzeichen und kommt andererseits im normalen Text vor). Die Software, die die Dateien erstellt, schreibt dann einen Backslash vor das Semikolon ("\;") und erkennt beim Einlesen, dass dieses "escapete" Semikolon zum normalen Text gehört und nicht als Trennzeichen zu interpretieren ist. Ein derartiger String würde also zum Beispiel so aussehen:
String str = "Rot; Blau\;Gelb; Grün";


Die split() Methode soll also das Semikolon zwischen Blau und Gelb ignorieren und wieder ein Array mit drei Elementen erzeugen. Mit dem oben demonstrierten Split würde das nicht funktionieren. Das Resultat wäre ein Array mit vier Strings, wobei das Wort Blau im Ergebnis mit einem Backslash enden würde. Es muss ein regulärer Ausdruck her, der nur "matcht", wenn das Semikolon ohne vorheriges Escape-Symbol auftritt.
String[] split = str.split("(?<!\\\\);");

Dieser Ausdruck tut genau dies. Er schlägt zu, wenn er ein Semikolon vorfindet, vor dem kein Backslash steht. Die vier Backslashs sind nötig, weil der Backslash im regulären Ausdruck normalerweise auch ein Escape-Symbol ist. Um einen Backslash im Regex zu notieren, müssen also zwei Backslashs her. Da der Backslash in Java gleichermaßen genutzt wird, muss die Eingabe wiederum escpaed werden. Somit müssen vier Backslashs geschrieben werden. Vor den Backslashs kommt eine Technik zum Einsatz (?<!), die man "Negative Lookbehind" nennt. Sie bringt den Regex-Matcher dazu, noch einmal ein Zeichen zurückzugehen und zu überprüfen, ob es ein Backslash ist. Nur wenn dies nicht der Fall ist, wird der Split durchgeführt. Wer sich dazu belesen will, sollte hier mal einen Blick drauf werfen.

Regex für Texte, die keine regulären Ausdrücke sind

Einen abschließenden Hinweis zu regulären Ausdrücken und der split() Funktion habe ich noch: Wann immer man einen Text anhand eines Zeichens oder einer Zeichenkette splitten will, die kein regulärer Ausdruck ist, sollte man diese zum regulären Ausdruck machen. Tut man das nicht, kann es im schlimmsten Fall sein, dass Java Unsinn anstellt (nämlich dann, wenn die Zeichenkette aus Sonderzeichen besteht, die einen regulären Ausdruck erzeugen). Dies kann man ganz einfach machen, indem man die statische Funktion Pattern.quote(String s) der Klasse java.util.regex.Pattern benutzt.
String[] split = str.split(Pattern.quote("."));

Dieser Aufruf würde den String anhand von Punkten im Text splitten. Normalerweise würde Java den Punkt im Sinne eines regulären Ausdrucks interpretieren (da steht der Punkt für ein beliebiges Zeichen).

So, genug geregext.

Geschnatter

4 Kommentare, selbst mitschnattern << < Seite 1/1 > >>
Hans, am 12.10.2015 um 10:59 Uhr
Klasse
Sebastian, am 13.10.2015 um 10:00 Uhr
Danke. Da schalte doch doch gerne den Adblocker aus.
Rainer, am 20.01.2016 um 01:07 Uhr
ich nicht
BlueBook, am 20.04.2016 um 08:30 Uhr
Danke für den Hinweis mit Punkt - bin ich natürlich voll reingelaufen und hab mich gewundert ;)
Du hast mich vor der Verzweiflung gerettet! :)