0

I would like to remove all the "unnecessary" spaces from a string. Specifically:

"a b c d" => "a b c d" // spaces between two words are left in
" a b c d " => "a b c d" // spaces not between two words are removed
"a  b c   d" => "a b c d" // as are duplicate spaces

Is there any regex out there that I can put into String.replace() to do this for me?

Bluefire
  • 13,519
  • 24
  • 74
  • 118

5 Answers5

5

Use trim() to remove spaces at the ends of the strings, and regexp replacement to replace multiple spaces in the middle.

str = str.trim().replace(/\s{2,}/g, ' ');
Barmar
  • 741,623
  • 53
  • 500
  • 612
3

Use split, filter and join. This will split the string, filter out the extra empty array entries then rejoin them with a space:

variable.split(" ").filter(Boolean).join(" ");
asdf
  • 2,927
  • 2
  • 21
  • 42
  • Ah, of course. Thank you for the answer, but I should have thought of that myself :) – Bluefire Sep 02 '15 at 21:37
  • 1
    @Qix Performance was not among the requirements that OP stated. It it obviously important to **you**, but to show how the problem can be solved this is still the most *human readable* way to do it. As long as performance does not become an issue, I'd prefer this alot over your favored solution. – connexo Sep 02 '15 at 22:40
  • @connexo [Performance is a feature.](http://blog.codinghorror.com/performance-is-a-feature/) It should be a consideration in everything you do coding-wise. Always. It might be a cute one-liner, but the fact is is that it's non-performant and incredibly obtuse. – Qix - MONICA WAS MISTREATED Sep 02 '15 at 22:41
  • @Qix Performance is a feature, but if the gains from performance are marginal (as they most likely are in this case) readability is favorable. [Readability vs Performance](http://stackoverflow.com/questions/19709334/readability-vs-performance) – asdf Sep 02 '15 at 22:43
  • 1
    @asdf `String.replace` is incredibly readable - it's one function call vs. three. As well, this answer is **5x slower** than the other answers. I understand the necessity of readability, but in this case it's a no brainer. – Qix - MONICA WAS MISTREATED Sep 02 '15 at 22:45
  • 1
    @connexo "this is still the most human readable way to do it" --- well, it's far from readability and semantic: the question is about removing (replacing) substrings from a string, not about splitting a string into chunks. I honestly don't believe someone would find `"foo".replace` code less readable than this. – zerkms Sep 02 '15 at 22:46
  • 1
    So readability in JS code does in your opinion involve knowledge about regex syntax? I do recognize the power in regular expressions - and that was actually what OP asked for - but I wouldn't exactly consider regexes as human readable. – connexo Sep 02 '15 at 22:51
  • 1
    @connexo it's more about `String.prototype.replace` semantics. It clearly addresses the operation to be performed: to replace a substring with another substring. And yes, I believe understanding `/\s{2,}/g` is a strong "must" requirement for a developer. And yes, I find this regex trivial and 101 of regexes. – zerkms Sep 02 '15 at 22:52
  • @connexo regexes are neither readable nor unreadable. The official Email regex is unreadable; `\s+` is readable. If you don't know regex, you're going to have a hard time with Javascript since it's heavily used. – Qix - MONICA WAS MISTREATED Sep 02 '15 at 22:54
3

This should work in ES 3 enabled browsers as well.

function deleteUnwantedWhitespace (searchstring) {
   searchstring = searchstring.trim().split(" ");
   var tempArray = [];
   for (var i = 0; i < searchstring.length; i++) {
      if (searchstring[i]) {
          tempArray.push(searchstring[i]);
      }
   }
   return tempArray.join(" ");
}

Edit: I just learned that String.prototype.trim is part of ES 5.1, so here's the polyfill:

if (!String.prototype.trim) {
  String.prototype.trim = function () {
    return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
  };
}
connexo
  • 53,704
  • 14
  • 91
  • 128
1

Do it manually

var strArr = ["a b c d", " a b c d ", "a  b c   d"];

for (var i = 0; i < strArr.length; i++) {
  console.log(removeSpaces(strArr[i]));
}

function removeSpaces(str) {
  str = str.replace(/ +/g, ' ');
  str = str.trim();

  return str;
}
Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145
AmmarCSE
  • 30,079
  • 5
  • 45
  • 53
0

Perfectly possible. The first regex replaces 1 or more \s characters with a single space. This includes spaces, tabs, and new-lines.

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

If you just want spaces, use

str.replace(/ +/g, ' ');

This is also more than 5x faster than using a Boolean filter.

Qix - MONICA WAS MISTREATED
  • 14,451
  • 16
  • 82
  • 145