Geteilte Zeichenfolge mit Punkt als Trennzeichen

99

Ich frage mich, ob ich eine Saite .richtig spalten werde ? Mein Code lautet:

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

Ich brauche nur den ersten Teil der Zeichenfolge, deshalb gebe ich den ersten Artikel zurück. Ich frage, weil ich in der API bemerkt habe, dass .dies ein beliebiges Zeichen bedeutet, also stecke ich jetzt fest.

Dean
quelle

Antworten:

173

split()Akzeptiert einen regulären Ausdruck, müssen Sie also entkommen, .um ihn nicht als Regex-Metazeichen zu betrachten. Hier ist ein Beispiel:

String[] fn = filename.split("\\."); 
return fn[0];
Marimuthu Madasamy
quelle
17

Split verwendet reguläre Ausdrücke, wobei '.' ist ein Sonderzeichen, das alles bedeutet. Sie müssen ihm entkommen, wenn Sie tatsächlich möchten, dass er mit dem '.' Charakter:

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

(ein '\', um das '.' im regulären Ausdruck zu umgehen, und das andere, um das erste in der Java-Zeichenfolge zu umgehen)

Außerdem würde ich nicht empfehlen, fn [0] zurückzugeben, da Sie something.blabla.txtden tatsächlichen Dateinamen nicht zurückgeben, wenn Sie eine Datei mit dem Namen " gültiger Name" haben. Stattdessen denke ich, dass es besser ist, wenn Sie verwenden:

int idx = filename.lastIndexOf('.');
return filename.subString(0, idx);
Andrei Fierbinteanu
quelle
Die Frage ist mit Java gekennzeichnet, nicht mit Javascript, mit dem Sie verlinkt haben.
Andrei Fierbinteanu
17

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

Problem

Sie müssen einige Dinge wissen text.split(delim). splitMethode:

  1. akzeptiert als Argument den regulären Ausdruck (Regex), der das Trennzeichen beschreibt, auf das wir uns aufteilen möchten.
  2. wenn delimam Ende von textlike in existierta,b,c,, (wo Trennzeichen ist ,) vorhanden ist, splitwird zunächst ein Array like erstellt, ["a" "b" "c" "" ""]aber da wir diese nachgestellten leeren Zeichenfolgen in den meisten Fällen nicht wirklich benötigen, werden sie auch automatisch für uns entfernt. Es wird also ein weiteres Array ohne diese nachfolgenden leeren Zeichenfolgen erstellt und zurückgegeben .

Sie müssen auch wissen, dass der Punkt. ein Sonderzeichen ist in Regex ist . Es stellt ein beliebiges Zeichen dar (außer Zeilentrennzeichen, dies kann jedoch mit dem Pattern.DOTALLFlag geändert werden ).

Also für String wie "abc"wenn wir auf "." splitMethode teilen

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

was bedeutet, dass wir als Ergebnis ein leeres Array erhalten [] (ohne Elemente, nicht einmal leere Zeichenfolge), sodass wir es nicht verwenden können, fn[0]da es keinen Index 0 gibt.

Lösung

Um dieses Problem zu lösen, müssen Sie lediglich einen regulären Ausdruck erstellen, der den Punkt darstellt. Dazu müssen wir dem entkommen .. Es gibt nur wenige Möglichkeiten, dies zu tun, aber die einfachste ist wahrscheinlich die Verwendung von \(was in String als "\\"weil geschrieben werden muss\ es dort auch etwas Besonderes ist und erfordert, dass ein anderer \maskiert wird).

Die Lösung Ihres Problems könnte also so aussehen

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

Bonus

Sie können auch andere Möglichkeiten verwenden, um diesem Punkt zu entkommen

  • mit Zeichenklasse split("[.]")
  • in Zitat einwickeln split("\\Q.\\E")
  • Verwenden der richtigen Pattern-Instanz mit Pattern.LITERAL Flag
  • oder verwenden Sie einfach split(Pattern.quote("."))und lassen Sie Regex für Sie entkommen.
Pshemo
quelle
das .. Ich mag das wirklich: split("[.]")
Dragonborn vor
15

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

filename.split("\\.");

oder die Split-Methode anweisen, bei 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. Innerhalb von Zeichenklassen wird das "." ist kein Sonderzeichen ("Metazeichen").

f1sh
quelle
@MisterSmith Vielleicht möchten Sie hier einen Blick auf die Programmiersprache werfen. Wir sprechen von Java, nicht von Javascript.
f1sh
Du liegst absolut richtig. Ich war gestern müde, weil ich in beiden Sprachen programmiert hatte und die Java-Datentypen nicht bemerkt hatte. Ich dachte, dass die Antworten 2010 vielleicht richtig waren, aber irgendwie haben sich die Browser heute anders verhalten.
Mister Smith
7

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

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

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

Neel
quelle
3
String str="1.2.3";
String[] cats = str.split(Pattern.quote("."));
Magnus Persson
quelle
2

Wäre es nicht effizienter zu bedienen?

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

Wenn Sie nur wollen, was ist bis zum ersten Punkt?

Martin Smith
quelle
2

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

java.util.regex
static String quote(String s) 
Christian Ullenboom
quelle
1

Die Aufteilung muss Regex als Argument nehmen ... Wechseln Sie einfach "."zu"\\."

Bob Fincheimer
quelle
0

Hinweis: Bei diesem Snippet ist weitere Vorsicht geboten, auch wenn der Punkt nicht mehr angezeigt wird!

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

Dies liegt daran, dass beim Teilen mindestens einmal übereinstimmende leere Zeichenfolgen (also auch die vor dem Punkt!) Aus dem Array entfernt werden, wenn das Muster mindestens einmal übereinstimmt , sodass ein leeres Array zurückgegeben werden muss.

avl42
quelle
Die einfachste Lösung in Fällen wie dem vorliegenden besteht darin, dem Aufruf zum Teilen auch ein Limit-Argument von 2 zu übergeben: String [] fn = filename.split ("[.]", 2);
avl42
0

Die Lösung, die für mich funktioniert hat, ist die folgende

Dateiname.split ("[.]");

Jorge Santos
quelle
0

Mit ApacheCommons ist es am einfachsten:

File file = ...
FilenameUtils.getBaseName(file.getName());

Beachten Sie, dass auch ein Dateiname aus dem vollständigen Pfad extrahiert wird.

Nikita
quelle
-2

splitnimmt einen regulären Ausdruck als Argument. So sollten Sie passieren "\."statt , "."da "."ist ein Metazeichen in regulären Ausdruck.

Vijay Mathew
quelle