Вирази регулярних виразів на Java, \\ s проти \\ s +


96

Яка різниця між наступними двома виразами?

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

3
Квантори, прочитайте їх.
jn1kk

Відповіді:


88

Перший відповідає одному пробілу, тоді як другий відповідає одному або кільком пробілам. Вони є так званими кванторами регулярних виразів, і вони виконують подібні збіги (взяті з документації ):

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
Мені завжди подобалося, як вони подають окремі описи жадібних, неохочих і прихильних версій кожного квантора, а потім говорять абсолютно те саме про всі три. ;)
Алан Мур

60

Ці два replaceAllдзвінки завжди дадуть однаковий результат, незалежно від того, що xє. Однак важливо зазначити, що два регулярні вирази неоднакові:

  • \\s - відповідає одному пробілу
  • \\s+ - відповідає послідовності одного або декількох пробілів.

У цьому випадку це не має значення, оскільки ви замінюєте все порожнім рядком (хоча було б краще використовувати \\s+з точки зору ефективності). Якби ви замінювали не пустим рядком, вони поводилися б по-різному.


Напишіть свій перший рядок, якщо x - "Забронюйте свій домен та завітайте \ n \ n \ n \ n \ n \ n Сьогодні в Інтернет". Чи дадуть обидва однакові результати?
sofs1

3
@ user3705478 Обидва результати дадуть однакові результати, навіть якщо один за одним буде кілька пробілів. Різниця полягає у способі обробки. Якщо у вас буде група (наприклад) 3 пробілів, що безпосередньо йдуть один за одним, \\ s + бере цю групу і перетворює її цілу в "", тоді як \\ s обробляє кожен простір самостійно.
Денні

11

Перш за все потрібно зрозуміти, що кінцевий результат обох висловлювань буде однаковим, тобто видалити всі пробіли з заданого рядка.

Однак x.replaceAll("\\s+", "");буде більш ефективним способом обрізання пробілів (якщо рядок може мати кілька суміжних пробілів) через потенційно меншу кількість замін через те, що регулярний вираз \\s+відповідає 1 або більше пробілам одночасно і замінює їх порожнім рядком.

Отже, навіть якщо ви отримуєте однакові результати з обох, краще використовувати:

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

2

Перший регулярний вираз буде відповідати одному пробілу. Другий регулярний вираз неохоче збігатиметься з одним або кількома пробілами. Для більшості цілей ці два регулярні вирази дуже схожі, за винятком другого випадку, регулярний вираз може збігатися з більшою кількістю рядка, якщо це запобігає відмові збігу регулярних виразів. з http://www.coderanch.com/t/570917/java/java/regex-difference


Почухайте слово "неохоче". Це питання стосується \s+, а не \s+?того іншого питання.
Алан Мур
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.