Java RegEx Metazeichen (.) Und gewöhnlicher Punkt?

150

Wie Sie in Java RegEx den Unterschied zwischen .(Punkt) dem Metazeichen und dem normalen Punkt herausfinden, wie wir ihn in einem Satz verwenden. Wie für andere Metazeichen diese Art von Situation zu handhaben zu wie ( *, +, \d, ...)

JavaUser
quelle

Antworten:

276

Wenn der Punkt oder andere Zeichen mit einer besonderen Bedeutung in regulären Ausdrücken ein normales Zeichen sein sollen, müssen Sie ihn mit einem Backslash maskieren. Da reguläre Ausdrücke in Java normale Java-Zeichenfolgen sind, müssen Sie den Backslash selbst umgehen, sodass Sie zwei Backslashes benötigen, z\\.

Fabian Steeg
quelle
1
Dieser Fix gilt auch für Bash
Krivar
18
Beachten Sie, dass es davon abhängt, wie Sie den regulären Ausdruck liefern, ob Sie dem Backslash entkommen möchten. Wenn Sie fest codiert sind, müssen Sie Folgendes verwenden: "\\." Wenn Sie aus einer Rohquelle (z. B. einer Textdatei) lesen, verwenden Sie nur einen einzigen Backslash: \.
Paul
25

Von den anderen Mitgliedern vorgeschlagene Lösungen funktionieren bei mir nicht.

Aber ich fand das:

Um einem Punkt in Java Regexp zu entkommen, schreiben Sie [.]

Kael
quelle
2
Das gleiche, \\.hat bei mir nicht funktioniert: Ich habe mich \.beschwert, dass .man nicht entkommen muss, \\.und dachte, es sei \.stattdessen ., \\\.und der Bauherr hat einen Fehler geworfen, [.]war das einzige, was funktioniert hat.
Mithunc
1
@mithunc Das ist seltsam, \\.in einem String-Literal finden Sie \., was der reguläre Ausdruck benötigt, um den Punkt als Literalpunkt anstelle des Matchers für beliebige Zeichen zu sehen.
Klaar
16

Reguläre Ausdrücke im Perl-Stil (auf denen die Java-Regex-Engine mehr oder weniger basiert) behandeln die folgenden Zeichen als Sonderzeichen:

.^$|*+?()[{\außerhalb von Zeichenklassen eine besondere Bedeutung haben ,

]^-\haben innerhalb von Zeichenklassen ( [...]) eine besondere Bedeutung .

Sie müssen diese (und nur diese) Symbole je nach Kontext umgehen (oder sie bei Zeichenklassen an Positionen platzieren, an denen sie nicht falsch interpretiert werden können).

Das unnötige Entkommen anderer Zeichen kann funktionieren, aber einige Regex-Engines behandeln dies als Syntaxfehler, was beispielsweise \_einen Fehler in .NET verursacht.

Einige andere führen zu falschen Ergebnissen, werden beispielsweise in Perl \<als Literal interpretiert <, egrepbedeuten aber "Wortgrenze".

So schreiben -?\d+\.\d+\$zu Spiel 1.50$, -2.00$usw. und [(){}[\]]für eine Zeichenklasse , die alle Arten von Klammern Spiele / Klammern / Klammern.

Wenn Sie eine Benutzereingabezeichenfolge in eine Regex-sichere Form umwandeln müssen, verwenden Sie java.util.regex.Pattern.quote.

Weiterführende Literatur: Jan Goyvaerts Blog RegexGuru über die Flucht vor Metazeichen

Tim Pietzcker
quelle
4

Entkomme Sonderzeichen mit einem Backslash. \., \*, \+, \\d, Und so weiter. Wenn Sie sich nicht sicher sind, können Sie sich jedem nicht alphabetischen Zeichen entziehen, unabhängig davon, ob es sich um ein besonderes Zeichen handelt oder nicht. Weitere Informationen finden Sie im javadoc für java.util.regex.Pattern .

Christoffer Hammarström
quelle
Das unnötige Entkommen von Nicht-Sonderzeichen funktioniert möglicherweise in einigen Sprachen, schlägt jedoch in anderen möglicherweise fehl. Daher ist es besser, sich nicht an die Gewohnheit zu gewöhnen.
Tim Pietzcker
1
Diese Frage bezieht sich jedoch speziell auf Java. In docs.oracle.com/javase/6/docs/api/java/util/regex/… heißt es: "Vor einem nicht alphabetischen Zeichen kann ein Backslash verwendet werden, unabhängig davon, ob es sich um ein Zeichen handelt." Teil eines nicht entflohenen Konstrukts. "
Christoffer Hammarström
2

Hier ist Code, den Sie direkt kopieren und einfügen können:

String imageName = "picture1.jpg";
String [] imageNameArray = imageName.split("\\.");
for(int i =0; i< imageNameArray.length ; i++)
{
   system.out.println(imageNameArray[i]);
}

Und was ist, wenn fälschlicherweise Leerzeichen vor oder nach "." in solchen Fällen? Es wird immer empfohlen, diese Bereiche ebenfalls zu berücksichtigen.

String imageName = "picture1  . jpg";
String [] imageNameArray = imageName.split("\\s*.\\s*");
    for(int i =0; i< imageNameArray.length ; i++)
    {
       system.out.println(imageNameArray[i]);
    }

Hier ist \\ s * da, um die Leerzeichen zu berücksichtigen und Ihnen nur die erforderlichen geteilten Zeichenfolgen zu geben.

Vyankatesh S Repal
quelle
1

Ich wollte eine Zeichenfolge finden, die mit ". *" Endet. Dazu musste ich Folgendes verwenden:

"^.*\\.\\*$"

Ein bisschen albern, wenn du darüber nachdenkst: D Hier ist, was es bedeutet. Am Anfang der Zeichenfolge kann ein beliebiges Zeichen null oder mehrmals stehen, gefolgt von einem Punkt "." gefolgt von einem Stern (*) am Ende der Zeichenfolge.

Ich hoffe, das ist nützlich für jemanden. Danke für den Backslash an Fabian.

Atspulgs
quelle
"\\.\\*$"Dann einfach benutzen . Es ist nicht erforderlich, den Anfang der Zeichenfolge abzugleichen, wenn es für Sie nicht wichtig ist.
Ophidian
Ja du hast Recht. Um ehrlich zu sein, kann ich mich nicht an den Anwendungsfall erinnern: /
Atspulgs
War nicht wirklich, um Ihnen zu helfen, sondern um anderen zu helfen, die sich Ihren Beitrag
ansehen
0

Wenn Sie beenden möchten, überprüfen Sie, ob Ihr Satz mit ". " Endet , und fügen Sie am Ende Ihres Musters [\. \ ] $ Hinzu.

Madhu Gogineni
quelle
0

Ich mache ein grundlegendes Array in JGrasp und habe festgestellt, dass mit einer Zugriffsmethode für ein char [] [] Array ('.') Ein einzelner Punkt platziert werden kann.

rgm
quelle