Wyrażenia regex w Javie, \\ s kontra \\ s +


97

Jaka jest różnica między następującymi dwoma wyrażeniami?

x = x.replaceAll("\\s", "");
x = x.replaceAll("\\s+", "");

Odpowiedzi:


89

Pierwsza z nich dopasowuje pojedynczą białą spację, a druga jedną lub wiele białych znaków. Są to tak zwane kwantyfikatory wyrażeń regularnych i wykonują takie dopasowania (zaczerpnięte z dokumentacji ):

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

21
Zawsze podobał mi się sposób, w jaki dostarczają oddzielne opisy chciwych, niechętnych i zaborczych wersji każdego kwantyfikatora, a następnie mówią dokładnie to samo o wszystkich trzech. ;)
Alan Moore

60

Te dwa replaceAllwywołania zawsze dadzą ten sam wynik, niezależnie od tego, co xsię stanie. Należy jednak pamiętać, że te dwa wyrażenia regularne nie są takie same:

  • \\s - dopasowuje pojedynczy biały znak
  • \\s+ - dopasowuje sekwencję jednego lub więcej białych znaków.

W tym przypadku nie ma to znaczenia, ponieważ zastępujesz wszystko pustym ciągiem (chociaż \\s+z punktu widzenia wydajności byłoby to lepsze ). Gdybyś zastąpił niepustym łańcuchem, oba zachowywałyby się inaczej.


Wpisz swój pierwszy wiersz, jeśli x to „Zarezerwuj domenę i uzyskaj \ n \ n \ n \ n \ n \ n dzisiaj online”. Czy oba dadzą takie same wyniki?
sofs1

3
@ user3705478 Oba dadzą te same wyniki, nawet jeśli wystąpi wiele spacji po sobie. Różnica polega na sposobie, w jaki jest obsługiwany. Jeśli miałbyś grupę (na przykład) 3 spacji bezpośrednio następujących po sobie, \\ s + bierze tę grupę i zamienia ją w całość w "", podczas gdy \\ s przetwarzałby każdą przestrzeń samodzielnie.
Dennie,

11

Przede wszystkim musisz zrozumieć, że ostateczne wyjście obu instrukcji będzie takie samo, tj. Usunięcie wszystkich spacji z podanego ciągu.

Jednak x.replaceAll("\\s+", "");będzie bardziej efektywny sposób przycinania spacji (jeśli ciąg może mieć wiele ciągłych spacji) z powodu potencjalnie mniejszej liczby zamienników ze względu na fakt, że wyrażenie regularne\\s+ dopasowuje 1 lub więcej spacji jednocześnie i zastępuje je pustym ciągiem.

Więc nawet jeśli otrzymujesz ten sam wynik z obu, lepiej jest użyć:

x.replaceAll("\\s+", "");

2

Pierwsze wyrażenie regularne dopasuje jeden biały znak. Drugi regex niechętnie dopasuje jeden lub więcej białych znaków. W większości przypadków te dwa wyrażenia regularne są bardzo podobne, z wyjątkiem drugiego przypadku, że wyrażenie regularne może dopasować większą część ciągu, jeśli zapobiega niepowodzeniu dopasowania wyrażenia regularnego. z http://www.coderanch.com/t/570917/java/java/regex-difference


Podrap słowo „niechętnie”. To pytanie dotyczy \s+, a nie \s+?innego pytania.
Alan Moore,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.