web-dev-qa-db-de.com

Zeichenfolge mit Punkt als Trennzeichen trennen

Ich frage mich, ob ich einen String . richtig aufteilen möchte? Mein Code lautet: 

String[] fn = filename.split(".");
return fn[0];

Ich brauche nur den ersten Teil der Zeichenkette, deshalb schicke ich den ersten Artikel zurück. Ich frage, weil mir in der API aufgefallen ist, dass . ein beliebiges Zeichen bedeutet. Jetzt bin ich festgefahren.

84
Dean

Da split() einen regulären Ausdruck akzeptiert, müssen Sie . mit Escapezeichen versehen, um ihn nicht als Regex-Metazeichen zu betrachten. Hier ist ein Beispiel:

String[] fn = filename.split("\\."); 
return fn[0];
152

Split verwendet reguläre Ausdrücke, wobei '.' ist ein Sonderzeichen, das etwas bedeutet. Sie müssen es entziehen, wenn Sie möchten, dass es mit dem '.' Übereinstimmt. Charakter:

String[] fn = filename.split("\\.");

(Ein '\' um das '.' im regulären Ausdruck zu entgehen, das andere um das erste im Java-String zu entgehen)

Ich würde auch nicht empfehlen, fn [0] zurückzugeben, da bei einer Datei mit dem Namen something.blabla.txt, die ein gültiger Name ist, der tatsächliche Dateiname nicht zurückgegeben wird. Stattdessen denke ich, es ist besser, wenn Sie verwenden:

int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);
16

die String # split (String) -Methode verwendet reguläre Ausdrücke. Zeichen bedeutet "beliebiges Zeichen" . Sie können dieses Verhalten vermeiden, indem Sie entweder das "."

filename.split("\\.");

oder teilen Sie die split-Methode mit, um in einer Zeichenklasse zu teilen:

filename.split("[.]");

Zeichenklassen sind Sammlungen von Zeichen. Du könntest schreiben

filename.split("[-.;ld7]");

und Dateiname würde bei jedem "-", ".", ";", "l", "d" oder "7" aufgeteilt werden. Innerhalb von Zeichenklassen wird das "." ist kein Sonderzeichen ("Metazeichen").

14
f1sh

Ich sehe hier nur Lösungen, aber keine vollständige Erklärung des Problems. Daher habe ich beschlossen, diese Antwort zu posten

Problem

Sie müssen ein paar Dinge über text.split(delim) wissen. split Methode:

  1. akzeptiert als Argument regulärer Ausdruck (Regex), der das Trennzeichen beschreibt, auf das wir aufteilen möchten. 
  2. wenn delim am Ende von text vorhanden ist, wie in a,b,c,, (wobei Trennzeichen , ist), erstellt split zuerst ein Array wie ["a" "b" "c" "" ""]. Da diese abschließenden leeren Zeichenfolgen jedoch in den meisten Fällen nicht unbedingt erforderlich sind, werden sie automatisch für uns entfernt. Es erstellt also ein anderes Array ohne diese abschließenden leeren Zeichenfolgen und gibt es zurück.

Sie müssen auch wissen, dass dot .Sonderzeichen in regex ist. Es stellt ein beliebiges Zeichen dar (mit Ausnahme von Zeilentrennzeichen, dies kann jedoch mit dem Flag Pattern.DOTALL geändert werden).

Also für eine Zeichenkette wie "abc" wenn wir uns die "."split Methode teilen 

  1. array erstellen wie ["" "" "" ""]
  2. da dieses Array jedoch nur leere Zeichenfolgen enthält und sie alle nachlaufen, werden sie entfernt (wie im vorherigen zweiten Punkt gezeigt). 

das bedeutet, wir erhalten als Ergebnis ein leeres Array [] (ohne Elemente, nicht einmal eine leere Zeichenfolge). Daher können wir fn[0] nicht verwenden, da kein Index 0 vorhanden ist.

Lösung

Um dieses Problem zu lösen, müssen Sie lediglich Regex erstellen, der den Punkt darstellt. Dazu müssen wir diesem . entkommen. Es gibt wenige Möglichkeiten, dies zu tun, aber am einfachsten ist es wahrscheinlich, \ zu verwenden (was in String als "\\" geschrieben werden muss, da \ dort ebenfalls speziell ist und ein anderer \ muss mit Escapezeichen versehen werden).

So kann die Lösung für Ihr Problem aussehen

String[] fn = filename.split("\\.");

Bonus

Sie können auch andere Wege verwenden, um diesem Punkt zu entgehen 

  • verwenden der Zeichenklasse split("[.]")
  • es in quotesplit("\\Q.\\E") einwickeln
  • verwenden der richtigen Musterinstanz mit dem Flag Pattern.LITERAL
  • oder verwenden Sie einfach split(Pattern.quote(".")) und lassen Sie Regex für Sie flüchten.
11
Pshemo

Da DOT (.) Als Sonderzeichen und Split-Methode betrachtet wird, erwartet String einen regulären Ausdruck, den Sie wie folgt tun müssen: 

String[] fn = filename.split("\\.");
return fn[0];

In Java müssen die Sonderzeichen mit einem "\" gekennzeichnet werden. Da "\" jedoch auch ein Sonderzeichen in Java ist, müssen Sie es erneut mit einem anderen "\" escape!

6
Neel

Wäre es nicht effizienter zu benutzen

 filename.substring(0, filename.indexOf("."))

wenn Sie nur wollen, was bis zum ersten Punkt geht?

2
Martin Smith

Normalerweise ist es NICHT eine gute Idee, es von Hand zu demaskieren. In der Pattern-Klasse gibt es eine Methode für diese Aufgabe:

Java.util.regex
static String quote(String s) 
2
String str="1.2.3";
String[] cats = str.split(Pattern.quote("."));
2
Magnus Persson

Die Aufteilung muss Regex als Argument annehmen ... Ändern Sie einfach "." in "\\.".

1
Bob Fincheimer

Hinweis: Dieses Snippet sollte auch nach dem Fluchtpunkt noch weiter vorsichtig sein!

Wenn dateiname nur die Zeichenfolge "." Ist, hat fn noch eine Länge von 0 und fn [0] löst immer noch eine Ausnahme aus!

Dies ist der Fall, da, wenn das Muster mindestens einmal übereinstimmt, split alle nachfolgenden leeren Zeichenfolgen (also auch eine vor dem Punkt!) Aus dem Array verwerfen und ein leeres Array zurückgeben muss.

0
avl42