Espressioni regolari in Java, \\ s contro \\ s +


96

Qual è la differenza tra le seguenti due espressioni?

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

3
Quantificatori, leggeteli.
jn1kk

Risposte:


88

Il primo corrisponde a un singolo spazio bianco, mentre il secondo corrisponde a uno o più spazi bianchi. Sono i cosiddetti quantificatori di espressioni regolari e eseguono corrispondenze in questo modo (tratto dalla documentazione ):

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

20
Ho sempre amato il modo in cui forniscono descrizioni separate delle versioni avide, riluttanti e possessive di ciascun quantificatore, e poi dicono esattamente la stessa cosa su tutti e tre. ;)
Alan Moore

60

Queste due replaceAllchiamate produrranno sempre lo stesso risultato, indipendentemente da cosa xsia. Tuttavia, è importante notare che le due espressioni regolari non sono le stesse:

  • \\s - corrisponde a un singolo carattere di spazio vuoto
  • \\s+ - corrisponde alla sequenza di uno o più caratteri di spazio bianco.

In questo caso non fa differenza, dal momento che stai sostituendo tutto con una stringa vuota (anche se sarebbe meglio usarla \\s+dal punto di vista dell'efficienza). Se sostituissi con una stringa non vuota, i due si comporterebbero diversamente.


Scritta la prima riga, se x è "Prenota il tuo dominio e accedi \ n \ n \ n \ n \ n \ n Online oggi". Entrambi produrranno gli stessi risultati?
sofs1

3
@ user3705478 Entrambi produrranno gli stessi risultati, anche se ci sarebbero più spazi uno dopo l'altro. La differenza sta nel modo in cui viene gestita. Se avessi un gruppo di (per esempio) 3 spazi che si susseguono direttamente, \\ s + prende quel gruppo e lo trasforma in un "", mentre \\ s analizza ogni spazio da solo.
Dennie

11

Prima di tutto devi capire che l'output finale di entrambe le istruzioni sarà lo stesso, ovvero rimuovere tutti gli spazi dalla stringa data.

Tuttavia, x.replaceAll("\\s+", "");sarà un modo più efficiente di tagliare gli spazi (se la stringa può avere più spazi contigui) a causa del numero potenzialmente inferiore di sostituzioni dovuto al fatto che regex \\s+corrisponde a 1 o più spazi contemporaneamente e li sostituisce con una stringa vuota.

Quindi, anche se ottieni lo stesso output da entrambi, è meglio usare:

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

2

La prima espressione regolare corrisponderà a un carattere di spazio bianco. La seconda regex corrisponderà con riluttanza a uno o più caratteri di spazio vuoto. Per la maggior parte degli scopi, queste due regex sono molto simili, tranne nel secondo caso, la regex può abbinare più della stringa, se impedisce che la corrispondenza regex fallisca. da http://www.coderanch.com/t/570917/java/java/regex-difference


Gratta la parola "con riluttanza". Questa domanda riguarda \s+, non \s+?come l'altra domanda.
Alan Moore
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.