[c#] How do I replace multiple spaces with a single space in C#?

How can I replace multiple spaces in a string with only one space in C#?

Example:

1 2 3  4    5

would be:

1 2 3 4 5

This question is related to c# regex string

The answer is


This is a shorter version, which should only be used if you are only doing this once, as it creates a new instance of the Regex class every time it is called.

temp = new Regex(" {2,}").Replace(temp, " "); 

If you are not too acquainted with regular expressions, here's a short explanation:

The {2,} makes the regex search for the character preceding it, and finds substrings between 2 and unlimited times.
The .Replace(temp, " ") replaces all matches in the string temp with a space.

If you want to use this multiple times, here is a better option, as it creates the regex IL at compile time:

Regex singleSpacify = new Regex(" {2,}", RegexOptions.Compiled);
temp = singleSpacify.Replace(temp, " ");

You can simply do this in one line solution!

string s = "welcome to  london";
s.Replace(" ", "()").Replace(")(", "").Replace("()", " ");

You can choose other brackets (or even other characters) if you like.


Consolodating other answers, per Joel, and hopefully improving slightly as I go:

You can do this with Regex.Replace():

string s = Regex.Replace (
    "   1  2    4 5", 
    @"[ ]{2,}", 
    " "
    );

Or with String.Split():

static class StringExtensions
{
    public static string Join(this IList<string> value, string separator)
    {
        return string.Join(separator, value.ToArray());
    }
}

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

I like to use:

myString = Regex.Replace(myString, @"\s+", " ");

Since it will catch runs of any kind of whitespace (e.g. tabs, newlines, etc.) and replace them with a single space.


Many answers are providing the right output but for those looking for the best performances, I did improve Nolanar's answer (which was the best answer for performance) by about 10%.

public static string MergeSpaces(this string str)
{

    if (str == null)
    {
        return null;
    }
    else
    {
        StringBuilder stringBuilder = new StringBuilder(str.Length);

        int i = 0;
        foreach (char c in str)
        {
            if (c != ' ' || i == 0 || str[i - 1] != ' ')
                stringBuilder.Append(c);
            i++;
        }
        return stringBuilder.ToString();
    }

}

I just wrote a new Join that I like, so I thought I'd re-answer, with it:

public static string Join<T>(this IEnumerable<T> source, string separator)
{
    return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}

One of the cool things about this is that it work with collections that aren't strings, by calling ToString() on the elements. Usage is still the same:

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

I know this is pretty old, but ran across this while trying to accomplish almost the same thing. Found this solution in RegEx Buddy. This pattern will replace all double spaces with single spaces and also trim leading and trailing spaces.

pattern: (?m:^ +| +$|( ){2,})
replacement: $1

Its a little difficult to read since we're dealing with empty space, so here it is again with the "spaces" replaced with a "_".

pattern: (?m:^_+|_+$|(_){2,})  <-- don't use this, just for illustration.

The "(?m:" construct enables the "multi-line" option. I generally like to include whatever options I can within the pattern itself so it is more self contained.


I just wrote a new Join that I like, so I thought I'd re-answer, with it:

public static string Join<T>(this IEnumerable<T> source, string separator)
{
    return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}

One of the cool things about this is that it work with collections that aren't strings, by calling ToString() on the elements. Usage is still the same:

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

I can remove whitespaces with this

while word.contains("  ")  //double space
   word = word.Replace("  "," "); //replace double space by single space.
word = word.trim(); //to remove single whitespces from start & end.

// Mysample string
string str ="hi you           are          a demo";

//Split the words based on white sapce
var demo= str .Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
        
//Join the values back and add a single space in between
str = string.Join(" ", demo);
// output: string str ="hi you are a demo";

Mix of StringBuilder and Enumerable.Aggregate() as extension method for strings:

using System;
using System.Linq;
using System.Text;

public static class StringExtension
{
    public static string StripSpaces(this string s)
    {
        return s.Aggregate(new StringBuilder(), (acc, c) =>
        {
            if (c != ' ' || acc.Length > 0 && acc[acc.Length-1] != ' ')
                acc.Append(c);

            return acc;
        }).ToString();
    }

    public static void Main()
    {
        Console.WriteLine("\"" + StringExtension.StripSpaces("1   Hello       World  2   ") + "\"");
    }
}

Input:

"1   Hello       World  2   "

Output:

"1 Hello World 2 "

try this method

private string removeNestedWhitespaces(char[] st)
{
    StringBuilder sb = new StringBuilder();
    int indx = 0, length = st.Length;
    while (indx < length)
    {
        sb.Append(st[indx]);
        indx++;
        while (indx < length && st[indx] == ' ')
            indx++;
        if(sb.Length > 1  && sb[0] != ' ')
            sb.Append(' ');
    }
    return sb.ToString();
}

use it like this:

string test = removeNestedWhitespaces("1 2 3  4    5".toCharArray());

Consolodating other answers, per Joel, and hopefully improving slightly as I go:

You can do this with Regex.Replace():

string s = Regex.Replace (
    "   1  2    4 5", 
    @"[ ]{2,}", 
    " "
    );

Or with String.Split():

static class StringExtensions
{
    public static string Join(this IList<string> value, string separator)
    {
        return string.Join(separator, value.ToArray());
    }
}

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

It's much simpler than all that:

while(str.Contains("  ")) str = str.Replace("  ", " ");

try this method

private string removeNestedWhitespaces(char[] st)
{
    StringBuilder sb = new StringBuilder();
    int indx = 0, length = st.Length;
    while (indx < length)
    {
        sb.Append(st[indx]);
        indx++;
        while (indx < length && st[indx] == ' ')
            indx++;
        if(sb.Length > 1  && sb[0] != ' ')
            sb.Append(' ');
    }
    return sb.ToString();
}

use it like this:

string test = removeNestedWhitespaces("1 2 3  4    5".toCharArray());

Another approach which uses LINQ:

 var list = str.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
 str = string.Join(" ", list);

I just wrote a new Join that I like, so I thought I'd re-answer, with it:

public static string Join<T>(this IEnumerable<T> source, string separator)
{
    return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}

One of the cool things about this is that it work with collections that aren't strings, by calling ToString() on the elements. Usage is still the same:

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

string xyz = "1   2   3   4   5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));

Old skool:

string oldText = "   1 2  3   4    5     ";
string newText = oldText
                    .Replace("  ", " " + (char)22 )
                    .Replace( (char)22 + " ", "" )
                    .Replace( (char)22 + "", "" );

Assert.That( newText, Is.EqualTo( " 1 2 3 4 5 " ) );

Mix of StringBuilder and Enumerable.Aggregate() as extension method for strings:

using System;
using System.Linq;
using System.Text;

public static class StringExtension
{
    public static string StripSpaces(this string s)
    {
        return s.Aggregate(new StringBuilder(), (acc, c) =>
        {
            if (c != ' ' || acc.Length > 0 && acc[acc.Length-1] != ' ')
                acc.Append(c);

            return acc;
        }).ToString();
    }

    public static void Main()
    {
        Console.WriteLine("\"" + StringExtension.StripSpaces("1   Hello       World  2   ") + "\"");
    }
}

Input:

"1   Hello       World  2   "

Output:

"1 Hello World 2 "

I looked over proposed solutions, could not find the one that would handle mix of white space characters acceptable for my case, for example:

  • Regex.Replace(input, @"\s+", " ") - it will eat your line breaks, if they are mixed with spaces, for example \n \n sequence will be replaced with
  • Regex.Replace(source, @"(\s)\s+", "$1") - it will depend on whitespace first character, meaning that it again might eat your line breaks
  • Regex.Replace(source, @"[ ]{2,}", " ") - it won't work correctly when there's mix of whitespace characters - for example "\t \t "

Probably not perfect, but quick solution for me was:

Regex.Replace(input, @"\s+", 
(match) => match.Value.IndexOf('\n') > -1 ? "\n" : " ", RegexOptions.Multiline)

Idea is - line break wins over the spaces and tabs.

This won't handle windows line breaks correctly, but it would be easy to adjust to work with that too, don't know regex that well - may be it is possible to fit into single pattern.


It's much simpler than all that:

while(str.Contains("  ")) str = str.Replace("  ", " ");

I like to use:

myString = Regex.Replace(myString, @"\s+", " ");

Since it will catch runs of any kind of whitespace (e.g. tabs, newlines, etc.) and replace them with a single space.


It's much simpler than all that:

while(str.Contains("  ")) str = str.Replace("  ", " ");

myString = Regex.Replace(myString, " {2,}", " ");

Without using regular expressions:

while (myString.IndexOf("  ", StringComparison.CurrentCulture) != -1)
{
    myString = myString.Replace("  ", " ");
}

OK to use on short strings, but will perform badly on long strings with lots of spaces.


I can remove whitespaces with this

while word.contains("  ")  //double space
   word = word.Replace("  "," "); //replace double space by single space.
word = word.trim(); //to remove single whitespces from start & end.

myString = Regex.Replace(myString, " {2,}", " ");

Consolodating other answers, per Joel, and hopefully improving slightly as I go:

You can do this with Regex.Replace():

string s = Regex.Replace (
    "   1  2    4 5", 
    @"[ ]{2,}", 
    " "
    );

Or with String.Split():

static class StringExtensions
{
    public static string Join(this IList<string> value, string separator)
    {
        return string.Join(separator, value.ToArray());
    }
}

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

Here is a slight modification on Nolonar original answer.

Checking if the character is not just a space, but any whitespace, use this:

It will replace any multiple whitespace character with a single space.

public static string FilterWhiteSpaces(string input)
{
    if (input == null)
        return string.Empty;

    var stringBuilder = new StringBuilder(input.Length);
    for (int i = 0; i < input.Length; i++)
    {
        char c = input[i];
        if (i == 0 || !char.IsWhiteSpace(c) || (char.IsWhiteSpace(c) && 
            !char.IsWhiteSpace(strValue[i - 1])))
            stringBuilder.Append(c);
    }
    return stringBuilder.ToString();
}

string xyz = "1   2   3   4   5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));

no Regex, no Linq... removes leading and trailing spaces as well as reducing any embedded multiple space segments to one space

string myString = "   0 1 2  3   4               5  ";
myString = string.Join(" ", myString.Split(new char[] { ' ' }, 
StringSplitOptions.RemoveEmptyEntries));

result:"0 1 2 3 4 5"


string xyz = "1   2   3   4   5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));

Here is a slight modification on Nolonar original answer.

Checking if the character is not just a space, but any whitespace, use this:

It will replace any multiple whitespace character with a single space.

public static string FilterWhiteSpaces(string input)
{
    if (input == null)
        return string.Empty;

    var stringBuilder = new StringBuilder(input.Length);
    for (int i = 0; i < input.Length; i++)
    {
        char c = input[i];
        if (i == 0 || !char.IsWhiteSpace(c) || (char.IsWhiteSpace(c) && 
            !char.IsWhiteSpace(strValue[i - 1])))
            stringBuilder.Append(c);
    }
    return stringBuilder.ToString();
}

I like to use:

myString = Regex.Replace(myString, @"\s+", " ");

Since it will catch runs of any kind of whitespace (e.g. tabs, newlines, etc.) and replace them with a single space.


I think Matt's answer is the best, but I don't believe it's quite right. If you want to replace newlines, you must use:

myString = Regex.Replace(myString, @"\s+", " ", RegexOptions.Multiline);

You can simply do this in one line solution!

string s = "welcome to  london";
s.Replace(" ", "()").Replace(")(", "").Replace("()", " ");

You can choose other brackets (or even other characters) if you like.


Regex can be rather slow even with simple tasks. This creates an extension method that can be used off of any string.

    public static class StringExtension
    {
        public static String ReduceWhitespace(this String value)
        {
            var newString = new StringBuilder();
            bool previousIsWhitespace = false;
            for (int i = 0; i < value.Length; i++)
            {
                if (Char.IsWhiteSpace(value[i]))
                {
                    if (previousIsWhitespace)
                    {
                        continue;
                    }

                    previousIsWhitespace = true;
                }
                else
                {
                    previousIsWhitespace = false;
                }

                newString.Append(value[i]);
            }

            return newString.ToString();
        }
    }

It would be used as such:

string testValue = "This contains     too          much  whitespace."
testValue = testValue.ReduceWhitespace();
// testValue = "This contains too much whitespace."

myString = Regex.Replace(myString, " {2,}", " ");

Use the regex pattern

    [ ]+    #only space

   var text = Regex.Replace(inputString, @"[ ]+", " ");

I know this is pretty old, but ran across this while trying to accomplish almost the same thing. Found this solution in RegEx Buddy. This pattern will replace all double spaces with single spaces and also trim leading and trailing spaces.

pattern: (?m:^ +| +$|( ){2,})
replacement: $1

Its a little difficult to read since we're dealing with empty space, so here it is again with the "spaces" replaced with a "_".

pattern: (?m:^_+|_+$|(_){2,})  <-- don't use this, just for illustration.

The "(?m:" construct enables the "multi-line" option. I generally like to include whatever options I can within the pattern itself so it is more self contained.


Use the regex pattern

    [ ]+    #only space

   var text = Regex.Replace(inputString, @"[ ]+", " ");

I think Matt's answer is the best, but I don't believe it's quite right. If you want to replace newlines, you must use:

myString = Regex.Replace(myString, @"\s+", " ", RegexOptions.Multiline);

I just wrote a new Join that I like, so I thought I'd re-answer, with it:

public static string Join<T>(this IEnumerable<T> source, string separator)
{
    return string.Join(separator, source.Select(e => e.ToString()).ToArray());
}

One of the cool things about this is that it work with collections that aren't strings, by calling ToString() on the elements. Usage is still the same:

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

Regex can be rather slow even with simple tasks. This creates an extension method that can be used off of any string.

    public static class StringExtension
    {
        public static String ReduceWhitespace(this String value)
        {
            var newString = new StringBuilder();
            bool previousIsWhitespace = false;
            for (int i = 0; i < value.Length; i++)
            {
                if (Char.IsWhiteSpace(value[i]))
                {
                    if (previousIsWhitespace)
                    {
                        continue;
                    }

                    previousIsWhitespace = true;
                }
                else
                {
                    previousIsWhitespace = false;
                }

                newString.Append(value[i]);
            }

            return newString.ToString();
        }
    }

It would be used as such:

string testValue = "This contains     too          much  whitespace."
testValue = testValue.ReduceWhitespace();
// testValue = "This contains too much whitespace."

For those, who don't like Regex, here is a method that uses the StringBuilder:

    public static string FilterWhiteSpaces(string input)
    {
        if (input == null)
            return string.Empty;

        StringBuilder stringBuilder = new StringBuilder(input.Length);
        for (int i = 0; i < input.Length; i++)
        {
            char c = input[i];
            if (i == 0 || c != ' ' || (c == ' ' && input[i - 1] != ' '))
                stringBuilder.Append(c);
        }
        return stringBuilder.ToString();
    }

In my tests, this method was 16 times faster on average with a very large set of small-to-medium sized strings, compared to a static compiled Regex. Compared to a non-compiled or non-static Regex, this should be even faster.

Keep in mind, that it does not remove leading or trailing spaces, only multiple occurrences of such.


Consolodating other answers, per Joel, and hopefully improving slightly as I go:

You can do this with Regex.Replace():

string s = Regex.Replace (
    "   1  2    4 5", 
    @"[ ]{2,}", 
    " "
    );

Or with String.Split():

static class StringExtensions
{
    public static string Join(this IList<string> value, string separator)
    {
        return string.Join(separator, value.ToArray());
    }
}

//...

string s = "     1  2    4 5".Split (
    " ".ToCharArray(), 
    StringSplitOptions.RemoveEmptyEntries
    ).Join (" ");

It's much simpler than all that:

while(str.Contains("  ")) str = str.Replace("  ", " ");

For those, who don't like Regex, here is a method that uses the StringBuilder:

    public static string FilterWhiteSpaces(string input)
    {
        if (input == null)
            return string.Empty;

        StringBuilder stringBuilder = new StringBuilder(input.Length);
        for (int i = 0; i < input.Length; i++)
        {
            char c = input[i];
            if (i == 0 || c != ' ' || (c == ' ' && input[i - 1] != ' '))
                stringBuilder.Append(c);
        }
        return stringBuilder.ToString();
    }

In my tests, this method was 16 times faster on average with a very large set of small-to-medium sized strings, compared to a static compiled Regex. Compared to a non-compiled or non-static Regex, this should be even faster.

Keep in mind, that it does not remove leading or trailing spaces, only multiple occurrences of such.


no Regex, no Linq... removes leading and trailing spaces as well as reducing any embedded multiple space segments to one space

string myString = "   0 1 2  3   4               5  ";
myString = string.Join(" ", myString.Split(new char[] { ' ' }, 
StringSplitOptions.RemoveEmptyEntries));

result:"0 1 2 3 4 5"


Old skool:

string oldText = "   1 2  3   4    5     ";
string newText = oldText
                    .Replace("  ", " " + (char)22 )
                    .Replace( (char)22 + " ", "" )
                    .Replace( (char)22 + "", "" );

Assert.That( newText, Is.EqualTo( " 1 2 3 4 5 " ) );

This is a shorter version, which should only be used if you are only doing this once, as it creates a new instance of the Regex class every time it is called.

temp = new Regex(" {2,}").Replace(temp, " "); 

If you are not too acquainted with regular expressions, here's a short explanation:

The {2,} makes the regex search for the character preceding it, and finds substrings between 2 and unlimited times.
The .Replace(temp, " ") replaces all matches in the string temp with a space.

If you want to use this multiple times, here is a better option, as it creates the regex IL at compile time:

Regex singleSpacify = new Regex(" {2,}", RegexOptions.Compiled);
temp = singleSpacify.Replace(temp, " ");

// Mysample string
string str ="hi you           are          a demo";

//Split the words based on white sapce
var demo= str .Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
        
//Join the values back and add a single space in between
str = string.Join(" ", demo);
// output: string str ="hi you are a demo";

string xyz = "1   2   3   4   5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));

Another approach which uses LINQ:

 var list = str.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
 str = string.Join(" ", list);

I looked over proposed solutions, could not find the one that would handle mix of white space characters acceptable for my case, for example:

  • Regex.Replace(input, @"\s+", " ") - it will eat your line breaks, if they are mixed with spaces, for example \n \n sequence will be replaced with
  • Regex.Replace(source, @"(\s)\s+", "$1") - it will depend on whitespace first character, meaning that it again might eat your line breaks
  • Regex.Replace(source, @"[ ]{2,}", " ") - it won't work correctly when there's mix of whitespace characters - for example "\t \t "

Probably not perfect, but quick solution for me was:

Regex.Replace(input, @"\s+", 
(match) => match.Value.IndexOf('\n') > -1 ? "\n" : " ", RegexOptions.Multiline)

Idea is - line break wins over the spaces and tabs.

This won't handle windows line breaks correctly, but it would be easy to adjust to work with that too, don't know regex that well - may be it is possible to fit into single pattern.


Many answers are providing the right output but for those looking for the best performances, I did improve Nolanar's answer (which was the best answer for performance) by about 10%.

public static string MergeSpaces(this string str)
{

    if (str == null)
    {
        return null;
    }
    else
    {
        StringBuilder stringBuilder = new StringBuilder(str.Length);

        int i = 0;
        foreach (char c in str)
        {
            if (c != ' ' || i == 0 || str[i - 1] != ' ')
                stringBuilder.Append(c);
            i++;
        }
        return stringBuilder.ToString();
    }

}

I like to use:

myString = Regex.Replace(myString, @"\s+", " ");

Since it will catch runs of any kind of whitespace (e.g. tabs, newlines, etc.) and replace them with a single space.