Есть ли разница между / \ s / g и / \ s + / g?

87

Когда у нас есть строка, содержащая символы пробела:

var str = '  A B  C   D EF ';

и мы хотим удалить пробелы из строки (мы хотим это :) 'ABCDEF'.

Оба это:

str.replace(/\s/g, '')

и это:

str.replace(/\s+/g, '')

вернет правильный результат.

Значит ли это, что +в данной ситуации лишнее? Есть ли разница между этими двумя регулярными выражениями в этой ситуации (например, могут ли они каким-либо образом давать разные результаты)?


Обновление: Сравнение производительности - /\s+/gбыстрее. Смотрите здесь: http://jsperf.com/s-vs-s

Шиме Видас
источник
1
vidas stackoverflow.com/questions/5963182/… Бьюсь об заклад, это то, что заставило вас задать этот вопрос;) (ваш комментарий к ответу)
rsplak
2
Я могу представить \s+, что это быстрее, потому что он может заменять куски пробелов, в то время как \sкаждый пробел должен заменяться отдельно?
KooiInc
1
@KooiInc: Верно, потому что он соответствует / заменяет меньшее количество раз.
BoltClock

Ответы:

214

В первом регулярном выражении каждый символ пробела заменяется символом за символом пустой строкой.

Во втором регулярном выражении каждая непрерывная строка пробелов заменяется пустой строкой из-за наличия +.

Однако так же, как 0, умноженный на что-либо еще, равен 0, кажется, что оба метода удаляют пробелы одинаково.

Если вы измените заменяющую строку на '#', разница станет намного яснее:

var str = '  A B  C   D EF ';
console.log(str.replace(/\s/g, '#'));  // ##A#B##C###D#EF#
console.log(str.replace(/\s+/g, '#')); // #A#B#C#D#EF#
BoltClock
источник
27

\sозначает «один пробел» и \s+означает «один или несколько пробелов».

Но поскольку вы используете /gфлаг (замените все вхождения) и заменяете его пустой строкой, ваши два выражения имеют одинаковый эффект.

Гонки легкости на орбите
источник
Но вторая версия наверняка будет быстрее.
Тим Пицкер
Значит ли это, что мне не нужно использовать / g, если я использую \ s +
Gaurav
1
@Gaurav: Нет. Потому что тогда он заменит только первый \s+, а остальные оставят нетронутыми. Например, ' foo bar '.replace(/\s+/, '')вы можете 'foo bar ' редактировать
объединяя
@Gaurav Я так не думаю. Если вы опустите gмодификатор, будет заменено только первое появление блока пробелов.
KooiInc
10

В случае совпадения первый будет возвращать одно совпадение на пробелы, тогда как второй вернет совпадение для каждой группы пробелов.

Результат тот же, потому что вы заменяете его пустой строкой. Если вы, например, замените его на «x», результаты будут другими.

str.replace(/\s/g, '') вернет 'xxAxBxxCxxxDxEF'

пока str.replace(/\s+/g, '')вернет 'xAxBxCxDxEF'

потому что \sсоответствует каждому пробелу, заменяя каждый символом 'x', и \s+сопоставляет группы пробелов, заменяя несколько последовательных пробелов одним 'x'.

Дуг
источник
3

+означает «один или несколько символов», а без плюса - «один символ». В вашем случае оба результата дают один и тот же результат.

Джош М.
источник