Regex-Ausdrücke in Java, \\ s vs. \\ s +

96

Was ist der Unterschied zwischen den folgenden beiden Ausdrücken?

x = x.replaceAll("\\s", "");
x = x.replaceAll("\\s+", "");
mpluse
quelle
3
Quantifizierer, lesen Sie sie nach.
jn1kk

Antworten:

88

Das erste entspricht einem einzelnen Leerzeichen, während das zweite einem oder mehreren Leerzeichen entspricht. Sie sind die sogenannten Quantifizierer für reguläre Ausdrücke und führen Übereinstimmungen wie diese durch (entnommen aus der Dokumentation ):

Greedy quantifiers
X?  X, once or not at all
X*  X, zero or more times
X+  X, one or more times
X{n}    X, exactly n times
X{n,}   X, at least n times
X{n,m}  X, at least n but not more than m times

Reluctant quantifiers
X?? X, once or not at all
X*? X, zero or more times
X+? X, one or more times
X{n}?   X, exactly n times
X{n,}?  X, at least n times
X{n,m}? X, at least n but not more than m times

Possessive quantifiers
X?+ X, once or not at all
X*+ X, zero or more times
X++ X, one or more times
X{n}+   X, exactly n times
X{n,}+  X, at least n times
X{n,m}+ X, at least n but not more than m times
Óscar López
quelle
19
Ich habe es immer geliebt, wie sie die gierigen, widerstrebenden und besitzergreifenden Versionen jedes Quantifizierers separat beschreiben und dann über alle drei genau dasselbe sagen. ;)
Alan Moore
60

Diese beiden replaceAllAufrufe führen immer zum gleichen Ergebnis, unabhängig davon, was es xist. Es ist jedoch wichtig zu beachten, dass die beiden regulären Ausdrücke nicht identisch sind:

  • \\s - Entspricht einem einzelnen Leerzeichen
  • \\s+ - Entspricht der Reihenfolge eines oder mehrerer Leerzeichen.

In diesem Fall macht es keinen Unterschied, da Sie alles durch eine leere Zeichenfolge ersetzen (obwohl es \\s+aus Effizienzgründen besser wäre, sie zu verwenden ). Wenn Sie durch eine nicht leere Zeichenfolge ersetzen würden, würden sich die beiden unterschiedlich verhalten.

arshajii
quelle
Schreiben Sie in Ihrer ersten Zeile "Wenn Sie Ihre Domain buchen und \ n \ n \ n \ n \ n \ n noch heute online gehen". Werden beide die gleichen Ergebnisse erzielen?
sofs1
3
@ user3705478 Beide führen zu denselben Ergebnissen, auch wenn mehrere Leerzeichen nacheinander stehen. Der Unterschied liegt in der Art und Weise, wie damit umgegangen wird. Wenn Sie eine Gruppe von (zum Beispiel) 3 Leerzeichen haben würden, die direkt aufeinander folgen, nimmt \\ s + diese Gruppe und verwandelt das Ganze in ein "", während \\ s jedes Leerzeichen für sich verarbeitet.
Dennie
11

Zunächst müssen Sie verstehen, dass die endgültige Ausgabe beider Anweisungen identisch ist, dh um alle Leerzeichen aus der angegebenen Zeichenfolge zu entfernen.

Dies x.replaceAll("\\s+", "");ist jedoch eine effizientere Methode zum Trimmen von Leerzeichen (wenn die Zeichenfolge mehrere zusammenhängende Leerzeichen enthalten kann), da möglicherweise weniger Ersetzungen erforderlich sind, da Regex \\s+mit einem oder mehreren Leerzeichen gleichzeitig übereinstimmt und diese durch leere Zeichenfolgen ersetzt.

Obwohl Sie von beiden die gleiche Ausgabe erhalten, ist es besser, Folgendes zu verwenden:

x.replaceAll("\\s+", "");
Anubhava
quelle
2

Der erste reguläre Ausdruck entspricht einem Leerzeichen. Die zweite Regex stimmt nur ungern mit einem oder mehreren Leerzeichen überein. Für die meisten Zwecke sind diese beiden regulären Ausdrücke sehr ähnlich, außer im zweiten Fall kann der reguläre Ausdruck mehr mit der Zeichenfolge übereinstimmen, wenn dadurch verhindert wird, dass die reguläre Übereinstimmung fehlschlägt. von http://www.coderanch.com/t/570917/java/java/regex-difference

Evgenyl
quelle
Kratz das Wort "widerwillig". Bei dieser Frage geht es \s+nicht um \s+?diese andere Frage.
Alan Moore