769

Given a string like:

"The dog      has a long   tail, and it     is RED!"

What kind of jQuery or JavaScript magic can be used to keep spaces to only one space max?

Goal:

"The dog has a long tail, and it is RED!"
TylerH
  • 20,799
  • 66
  • 75
  • 101
AnApprentice
  • 108,152
  • 195
  • 629
  • 1,012

27 Answers27

1367

Given that you also want to cover tabs, newlines, etc, just replace \s\s+ with ' ':

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

If you really want to cover only spaces (and thus not tabs, newlines, etc), do so:

string = string.replace(/  +/g, ' ');
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 2
    Does this also remove, whitespacy tab characters? – AnApprentice Dec 30 '09 at 17:39
  • 2
    @nobosh: yes, it replaces all white-space characters (space, tab, \r, \n, \v \f) with space-character. – Rafael Dec 30 '09 at 17:40
  • 9
    This is not working when a blank instead of a tab or newline is needed. Right? /\s+/ would be working. – Fabian Feb 20 '13 at 11:01
  • 6
    it would might be better for you as a function such as `function removeExtraSpaces(string){ return string.replace(/\s{2,}/g, ' ');}` – Math chiller Sep 08 '13 at 23:03
  • Oracle version: SELECT regexp_replace('abc def a', '\s\s+', ' ') FROM DUAL – StewS2 Jan 21 '16 at 21:05
  • 1
    This doesn't remove the initial and trailing whitespaces. For that see [this answer](https://stackoverflow.com/a/39258021/235415). – Ethan Apr 12 '18 at 05:06
  • 9
    @Ethan: JS has a builtin function for that: `trim()`. It's faster than regex. You could just do `string.trim().replace(/\s\s+/g, ' ');` or `string.replace(/\s\s+/g, ' ').trim();`. – BalusC Apr 12 '18 at 06:12
  • 12
    `/\s\s+/g` and `/\s{2,}/g` do not match whitespacey characters unless there are at least two adjacent to each other, e.g. will match \t\t but will not match single \t. `string.replace(/\s+/g, ' ')` will match all single and multiple whitespacey character substrings and replace with single space. – remy-actual Sep 19 '18 at 23:08
  • @NadavB: if you're referring to the 2nd snippet; a newline is indeed not a space. – BalusC Feb 22 '19 at 17:49
  • @BalusC: When you replace `/\s+/` with a single space `' '`, you never end up with a sentence with no spaces at all. Am I still missing something? – Bugs Bunny Aug 13 '19 at 15:07
  • @BugsBunny: Sorry, I was not awake. The technical reason is performance. See next answer. – BalusC Aug 13 '19 at 18:54
240

Since you seem to be interested in performance, I profiled these with firebug. Here are the results I got:

str.replace( /  +/g, ' ' )       ->  380ms
str.replace( /\s\s+/g, ' ' )     ->  390ms
str.replace( / {2,}/g, ' ' )     ->  470ms
str.replace( / +/g, ' ' )        ->  790ms
str.replace( / +(?= )/g, ' ')    -> 3250ms

This is on Firefox, running 100k string replacements.

I encourage you to do your own profiling tests with firebug, if you think performance is an issue. Humans are notoriously bad at predicting where the bottlenecks in their programs lie.

(Also, note that IE 8's developer toolbar also has a profiler built in -- it might be worth checking what the performance is like in IE.)

Skippy le Grand Gourou
  • 6,976
  • 4
  • 60
  • 76
Edward Loper
  • 15,374
  • 7
  • 43
  • 52
  • 6
    http://jsperf.com/removing-multiple-spaces Go forth and JSPerf! The last method; `( / +(?= )/g, ' ');` fails in IE9, it leaves double spaces: `"Foo Bar Baz".replace(/ +(?= )/g, ' ');` --> `"Foo Bar Baz" ` – Joel Peltonen Apr 26 '13 at 10:22
  • @VivekPanday - I imagine that this is because the second line is only replacing occurrences of double spaces with a single space, while the first is replacing any space with a space as well. Whether this is time saved during the search or the actual replace, I don't know. – Maloric Aug 16 '16 at 11:27
  • This doesn't remove the initial and trailing whitespaces. For that see [this answer](https://stackoverflow.com/a/39258021/235415). – Ethan Apr 12 '18 at 05:04
55
var str = "The      dog        has a long tail,      and it is RED!";
str = str.replace(/ {2,}/g,' ');

EDIT: If you wish to replace all kind of whitespace characters the most efficient way would be like that:

str = str.replace(/\s{2,}/g,' ');
watain
  • 4,838
  • 4
  • 34
  • 35
18

A more robust method: This takes care of also removing the initial and trailing spaces, if they exist. Eg:

// NOTE the possible initial and trailing spaces
var str = "  The dog      has a long   tail, and it     is RED!  "

str = str.replace(/^\s+|\s+$|\s+(?=\s)/g, "");

// str -> "The dog has a long tail, and it is RED !"

Your example didn't have those spaces but they are a very common scenario too, and the accepted answer was only trimming those into single spaces, like: " The ... RED! ", which is not what you will typically need.

Ethan
  • 4,915
  • 1
  • 28
  • 36
17

This is one solution, though it will target all space characters:

"The      dog        has a long tail,      and it is RED!".replace(/\s\s+/g, ' ')

"The dog has a long tail, and it is RED!"

Edit: This is probably better since it targets a space followed by 1 or more spaces:

"The      dog        has a long tail,      and it is RED!".replace(/  +/g, ' ')

"The dog has a long tail, and it is RED!"

Alternative method:

"The      dog        has a long tail,      and it is RED!".replace(/ {2,}/g, ' ')
"The dog has a long tail, and it is RED!"

I didn't use /\s+/ by itself since that replaces spaces that span 1 character multiple times and might be less efficient since it targets more than necessary.

I didn't deeply test any of these so lmk if there are bugs.

Also, if you're going to do string replacement remember to re-assign the variable/property to its own replacement, eg:

var string = 'foo'
string = string.replace('foo', '')

Using jQuery.prototype.text:

var el = $('span:eq(0)');
el.text( el.text().replace(/\d+/, '') )
meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
  • 1
    The first one is totally pointless, \s\s+ means, an \s followed by one or more \s+, which can be reduced to a single \s+, the second example is more accurate because we only want to replace double spaces, not newlines, the third is more optimized because it only applies to examples with 2+ spaces. But str.replace(/ +(?= )/g,'');, only applies to examples with 2+ spaces but saves overwriting a space with a space step. – Evan Carroll Dec 30 '09 at 17:55
  • 4
    EvanCarroll you **fail** because \s\s+ is definitely different to \s+. \s\s+ would match '\t\t' or '\t\t\t' but NOT '\t'. And that's what it's all about, you don't want replace every f-en single whitespace character. – watain Dec 30 '09 at 18:11
  • I do. Used for full-text search (and snippet-display): No random tabs, non-breakers or thingymajigs, please. – T4NK3R Jan 21 '16 at 13:03
16

I have this method, I call it the Derp method for lack of a better name.

while (str.indexOf("  ") !== -1) {
    str = str.replace(/  /g, " ");
}

Running it in JSPerf gives some surprising results where it beat some of the more sophisticated approaches EDIT Original JSPerf link http://jsperf.com/removing-multiple-spaces/3 seems to be dead at the time

Joel Peltonen
  • 13,025
  • 6
  • 64
  • 100
12

Here is an alternate solution if you do not want to use replace (replace spaces in a string without using replace javascript)

var str="The dog      has a long   tail, and it     is RED!";
var rule=/\s{1,}/g;

str = str.split(rule).join(" "); 

document.write(str);
Narendra Jadhav
  • 10,052
  • 15
  • 33
  • 44
imos
  • 165
  • 1
  • 8
10

More robust:

function trim(word)
{
    word = word.replace(/[^\x21-\x7E]+/g, ' '); // change non-printing chars to spaces
    return word.replace(/^\s+|\s+$/g, '');      // remove leading/trailing spaces
}
james.garriss
  • 12,959
  • 7
  • 83
  • 96
Chris
  • 109
  • 1
  • 2
9

I suggest

string = string.replace(/ +/g," ");

for just spaces
OR

string = string.replace(/(\s)+/g,"$1");

for turning multiple returns into a single return also.

Leonard Meagher
  • 139
  • 1
  • 2
5

Also a possibility:

str.replace( /\s+/g, ' ' )
rfunduk
  • 30,053
  • 5
  • 59
  • 54
5

I know that I am late to the party, but I discovered a nice solution.

Here it is:

var myStr = myStr.replace(/[ ][ ]*/g, ' ');
ToXic73
  • 332
  • 6
  • 15
4

Comprehensive unencrypted answer for newbies et al.

This is for all of the dummies like me who test the scripts written by some of you guys which do not work.

The following 3 examples are the steps I took to remove special characters AND extra spaces on the following 3 websites (all of which work perfectly) {1. EtaVisa.com 2. EtaStatus.com 3. Tikun.com} so I know that these work perfectly.

We have chained these together with over 50 at a time and NO problems.

// This removed special characters + 0-9 and allows for just letters (upper and LOWER case)

function NoDoublesPls1()
{
var str=document.getElementById("NoDoubles1");
var regex=/[^a-z]/gi;
str.value=str.value.replace(regex ,"");
}

// This removed special characters and allows for just letters (upper and LOWER case) and 0-9 AND spaces

function NoDoublesPls2()
{
var str=document.getElementById("NoDoubles2");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"");
}

// This removed special characters and allows for just letters (upper and LOWER case) and 0-9 AND spaces // The .replace(/\s\s+/g, " ") at the end removes excessive spaces // when I used single quotes, it did not work.

function NoDoublesPls3()
{    var str=document.getElementById("NoDoubles3");
var regex=/[^a-z 0-9]/gi;
str.value=str.value.replace(regex ,"") .replace(/\s\s+/g, " ");
}

::NEXT:: Save #3 as a .js // I called mine NoDoubles.js

::NEXT:: Include your JS into your page

 <script language="JavaScript" src="js/NoDoubles.js"></script>

Include this in your form field:: such as

<INPUT type="text" name="Name"
     onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

So that it looks like this

<INPUT type="text" name="Name" onKeyUp="NoDoublesPls3()" onKeyDown="NoDoublesPls3()" id="NoDoubles3"/>

This will remove special characters, allow for single spaces and remove extra spaces.

semuzaboi
  • 4,972
  • 5
  • 20
  • 35
PatFoster
  • 49
  • 1
  • 2
2
var string = "The dog      has a long   tail, and it     is RED!";
var replaced = string.replace(/ +/g, " ");

Or if you also want to replace tabs:

var replaced = string.replace(/\s+/g, " ");
Brian Campbell
  • 322,767
  • 57
  • 360
  • 340
  • 1
    using + seems cleaner but it will also replace single spaces with single spaces, a little bit redundant and I'm not sure but it may create performace problems with a much longer text. – ahmetunal Dec 30 '09 at 17:39
  • 1
    I tend to use the shortest, simplest solution that will work, and only worry about that sort of optimization if I know that I need to be matching against a very large string, an at that point I will actually measure different solutions to see which will be faster. It can be hard to predict in advance what will be fastest without testing; for instance, in JavaScript interpreters, some complicated regular expressions will cause you to switch from a fast JIT compiled implementation to a slow interpreted one. – Brian Campbell Dec 30 '09 at 17:44
2

It's as easy as doing:

const myString = "  Hello     World       !   "
const parsed = myString.replace(/ +/g, ' ') // " Hello World ! "

Now, if you wanna get rid of the starting and ending spaces, you can do:

const trimmed = parsed.trim() // "Hello World !"

ONE LINER (TL;DR)

const parsedSTring = "   John     Doe    ".replace(/ +/g, ' ').trim() // "John Doe"
Miguel Jara
  • 311
  • 2
  • 9
1

// replace multiple white spaces with one white space

String replacedDisplayName = displayName.replaceAll("\\s{2,}", " ");
Amol Bais
  • 332
  • 1
  • 6
  • 30
  • `\s` means \s stands for “whitespace character”. ... That is: \s matches a space, a tab, a carriage return, a line feed, or a form feed. https://www.regular-expressions.info/shorthand.html – David Riccitelli Jan 18 '23 at 08:57
  • This doesn't work `'a b'.replaceAll("\\s{2,}", " ")` -> `'a b'` – Dominic Mar 06 '23 at 17:11
0
var myregexp = new RegExp(/ {2,}/g);

str = str.replace(myregexp,' ');
ahmetunal
  • 3,930
  • 1
  • 23
  • 26
0
var text = `xxx  df dfvdfv  df    
                     dfv`.split(/[\s,\t,\r,\n]+/).filter(x=>x).join(' ');

result:

"xxx df dfvdfv df dfv"
Toolkit
  • 10,779
  • 8
  • 59
  • 68
0

I know we have to use regex, but during an interview, I was asked to do WITHOUT USING REGEX.

@slightlytyler helped me in coming with the below approach.

const testStr = "I   LOVE    STACKOVERFLOW   LOL";

const removeSpaces = str  => {
  const chars = str.split('');
  const nextChars = chars.reduce(
    (acc, c) => {
      if (c === ' ') {
        const lastChar = acc[acc.length - 1];
        if (lastChar === ' ') {
          return acc;
        }
      }
      return [...acc, c];
    },
    [],
  );
  const nextStr = nextChars.join('');
  return nextStr
};

console.log(removeSpaces(testStr));
xSachinx
  • 53
  • 3
  • 2
    consider: console.log(testStr.split(" ").filter(s => s.length).join(" ")) – dpjanes Mar 28 '20 at 09:29
  • @dpjanes thanks, mate, do we have any similar chain function to get "DISTINCT" element from an array, we will be using the same array, no new array – xSachinx Jun 22 '20 at 15:09
  • 1
    hahah I love a challenge. Not fully chained, but one line: console.log(Array.from(new Set("I LOVE STACKOVERFLOW LOL LOVE".split(" ").filter(s => s.length))).join(" ")) – dpjanes Jun 23 '20 at 16:39
  • The core concept being Array.from(new Set()). – dpjanes Jun 23 '20 at 16:40
0

here is my solutions that work well for me:

var text = "    Tes ddas    dMd WAlkman 3Dsfd    "
    .toLowerCase()
    .replace(/\b\s+/g, " ")
    .replace(/\b\w/g, s => s.toUpperCase())
    .trimStart()
    .trimEnd();
    
console.log(text);

// result: Tes Ddas Dmd Walkman 3dsfd
sun sreng
  • 587
  • 6
  • 7
-1

We can use the following regex explained with the help of sed system command. The similar regex can be used in other languages and platforms.

Add the text into some file say test

manjeet-laptop:Desktop manjeet$ cat test
"The dog      has a long   tail, and it     is RED!"

We can use the following regex to replace all white spaces with single space

manjeet-laptop:Desktop manjeet$ sed 's/ \{1,\}/ /g' test
"The dog has a long tail, and it is RED!"

Hope this serves the purpose

minhas23
  • 9,291
  • 3
  • 58
  • 40
-1

Try this to replace multiple spaces with a single space.

<script type="text/javascript">
    var myStr = "The dog      has a long   tail, and it     is RED!";
    alert(myStr);  // Output 'The dog      has a long   tail, and it     is RED!'

    var newStr = myStr.replace(/  +/g, ' ');
    alert(newStr);  // Output 'The dog has a long tail, and it is RED!'
</script>

Read more @ Replacing Multiple Spaces with Single Space

jonathan klevin
  • 193
  • 1
  • 2
-1

For more control you can use the replace callback to handle the value.

value = "tags:HUNT  tags:HUNT         tags:HUNT  tags:HUNT"
value.replace(new RegExp(`(?:\\s+)(?:tags)`, 'g'), $1 => ` ${$1.trim()}`)
//"tags:HUNT tags:HUNT tags:HUNT tags:HUNT"
jackotonye
  • 3,537
  • 23
  • 31
-1

This script removes any white space (multiple spaces, tabs, returns, etc) between words and trims:

// Trims & replaces any wihtespacing to single space between words
String.prototype.clearExtraSpace = function(){
  var _trimLeft  = /^\s+/,
      _trimRight = /\s+$/,
      _multiple  = /\s+/g;

  return this.replace(_trimLeft, '').replace(_trimRight, '').replace(_multiple, ' ');
};
Oriol
  • 11,660
  • 5
  • 35
  • 37
-1

' mouse pointer touch '.replace(/^\s+|\s+$|(\s)+/g, "$1") should do the trick!

-1

Using nodepad++ function, below regex works fine for me,

Find: {1}\K\s+
Replace:leave it empty

Haji Rahmatullah
  • 390
  • 1
  • 2
  • 11
-2
let nameCorrection = function (str) {
  let strPerfect = str.replace(/\s+/g, " ").trim();
  let strSmall = strPerfect.toLowerCase();
  let arrSmall = strSmall.split(" ");
  let arrCapital = [];
  for (let x of arrSmall.values()) {
    arrCapital.push(x[0].toUpperCase() + x.slice(1));
  }

  let result = arrCapital.join(" ");
  console.log(result);
};
nameCorrection("Pradeep kumar dHital");
-2

def removeblanks(text): return re.sub(r'\s\s+'," ",text) I was working on a large textual data with a lot of duplicate spaces. The above RE worked for me. All the duplicate blank spaces were replaced by a single space.

Viraj
  • 1