573

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
uınbɐɥs
  • 7,236
  • 5
  • 26
  • 42
Pokus
  • 11,383
  • 11
  • 37
  • 27
  • 1
    a state machine can easily do it, but it's probably overkill if you need it only to remove spaces – Adrian Jan 06 '12 at 19:20
  • I've added a benchmark on the different ways to do this in a duplicate question http://stackoverflow.com/a/37592018/582061 . Regex was not the fastest way to do this. – Stian Standahl Jun 03 '16 at 04:42
  • Unless maybe it's a regional thing where people abbreviate "whitespace" as "space", I don't understand why so many answers are seeking to replace anything other than multiple consecutive [**space**](https://en.wikipedia.org/wiki/Space_(punctuation)) (i.e., `' '`, `'\u0020'`, `'\x20'`, `(char) 32`) characters. – Lance U. Matthews Mar 28 '22 at 10:35

28 Answers28

777

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.

Matt
  • 31,662
  • 4
  • 34
  • 33
  • 58
    Slight modification: Regex.Replace(source, @"(\s)\s+", "$1"); This will return the first whitespace type found. So if you have 5 tabs, it will return a tab. Incase someone prefers this. – F.B. ten Kate May 14 '12 at 12:56
  • @radistao Your link is for Javascript string replace, not for C#. – Shiva Apr 28 '14 at 17:58
  • 1
    @Shiva, /\s\s+/ is a standard POSIX regex statement and may be converted/used in any language using own syntax – radistao Apr 29 '14 at 06:45
  • @F.B.tenKate Good option. A further example is if you have tab-space-space-tab-newline, it will return a tab. – goodeye Jan 26 '15 at 03:28
  • 5
    In the spirit of @F.B.tenKate's solution: Regex.Replace(source, @"(\s)\1+", "$1"); will replace multiple *identical* consecutive characters by a single one. – François Beaune Jan 11 '16 at 17:06
  • 2
    in order to remove leading and trailing whitespaces you should use Trim() function with this,,like var myString = Regex.Replace(myString, @"\s+", " ").Trim(); – Harish Nayak Apr 03 '19 at 02:07
  • François suggestion is best if you want to respect user input (eg ideographic spaces being kept rather than being replaced by normal spaces) – MattWazEre May 28 '20 at 01:49
580
string sentence = "This is a sentence with multiple    spaces";
RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);     
sentence = regex.Replace(sentence, " ");
Patrick Desjardins
  • 136,852
  • 88
  • 292
  • 341
  • 4
    I have copy and paste that and it works. I really do not like REgex but this time it saves my life. – Pokus Oct 15 '08 at 22:22
  • 1
    This is good solution but unless you wrap it in a method most programmers will have no idea what it does. – Craig Oct 15 '08 at 22:27
  • 9
    @Craig a comment would suffice, IMO. // This block replaces multiple spaces with one... :) – paulwhit Oct 15 '08 at 23:40
  • 1
    @Pokus, RegEx is a wonderfully powerful tool to learn and use, once you just get past the initial learning curve, you'll wonder how you ever lived without it. – Mark Oct 15 '08 at 23:42
  • There's minor bug, should be @" ", not @"". – DK. Oct 20 '08 at 17:52
  • 6
    Really, RegEx is overkill for this. – Joel Coehoorn Oct 28 '08 at 15:01
  • 1
    You don't need the square brackets in the regex. Just use " {2,}". – Jan Goyvaerts Nov 20 '08 at 07:20
  • 12
    @Joel: Can't agree. I'm actually sure that this way is more efficient than yours for large enough strings and can be done in one single line. Where's the overkill? – Konrad Rudolph Nov 23 '08 at 16:27
  • 2
    Also regex is far more obvious than repeated find&replace IMHO. – lacop Nov 23 '08 at 16:34
  • The Regex could be compiled since it can be reused in its form. – Andrei Rînea May 24 '09 at 08:53
  • @Konrad Do you think it could be more efficient? hmm.. a simple loop through all characters of the text would be enough to do the same without using RegEx. (I love RegEx anyway :D) – Oscar Mederos Mar 04 '11 at 06:29
  • 32
    @Oscar Joel’s code isn’t a simple loop through all characters! It’s a hidden nested loop that has a quadratic worst case. This regular expression, by contrast, is linear, only builds up a single string (= drastically reduced allocation costs compared to Joel’s code) and furthermore the engine can optimize the hell out of it (to be honest, I doubt the .NET regex is smart enough for this but in theory this regular expression can be implemented so cheaply that it’s not even funny any more; it only needs a DFA with three states, one transition each, and no additional information). – Konrad Rudolph Mar 04 '11 at 10:17
  • this worked for me. Maybe you want to remove tabs. https://stackoverflow.com/a/26584593/2125322 If there is one space in the first char, you should remove it. https://stackoverflow.com/a/3381992/2125322 – matasoy Nov 14 '17 at 21:17
  • 1
    In one line: `Regex.Replace("multiple spaces", "[ ]{2,}", " ", RegexOptions.None)` – datchung May 14 '20 at 02:31
77
string xyz = "1   2   3   4   5";
xyz = string.Join( " ", xyz.Split( new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries ));
tvanfosson
  • 524,688
  • 99
  • 697
  • 795
43

Another approach which uses LINQ:

 var list = str.Split(' ').Where(s => !string.IsNullOrWhiteSpace(s));
 str = string.Join(" ", list);
cuongle
  • 74,024
  • 28
  • 151
  • 206
42

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);
Brenda Bell
  • 429
  • 4
  • 2
  • 5
    RegexOptions.Multiline changes the meaning of ^ and $ so they match the beginning and end of every line ($ = \n), instead of the whole multi-line string. Because \s is equivalent to [ \f\n\r\t\v] the newlines should be replaced even if Multiline option is off. – SushiGuy Jun 05 '12 at 23:27
  • 4
    Matt's answer has already covered this. I 'believe' 30 persons just blindfold up-voted this answer :) – 123iamking Sep 08 '17 at 03:50
31

It's much simpler than all that:

while(str.Contains("  ")) str = str.Replace("  ", " ");
Fahim Parkar
  • 30,974
  • 45
  • 160
  • 276
Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 25
    This will be far less efficient than the regex " {2,}" if the string contains sequences of 3 or more spaces. – Jan Goyvaerts Nov 20 '08 at 07:22
  • 2
    @JanGoyvaerts: Even with 10 spaces, the regex was slower when I made a quick and dirty test. That being said, it only takes one giant substring full of spaces to completely kill performance of the while loop. For fairness, I used I used RegexOptions.Compiled, rather than the slower Regex.Replace. – Brian Feb 06 '13 at 15:37
  • 6
    RegexOptions.Compiled adds a lot of overhead compiling the regex into IL. Don't use it unless your application will use the regex often enough or on large enough strings that the increased matching speed offsets the decreased compilation speed. – Jan Goyvaerts Feb 07 '13 at 04:26
  • This is an example of extreme inefficient code. LOL. – pcbabu Feb 19 '20 at 19:51
  • 2
    @pcbabu It's not as bad as it seems for many cases. The `Replace()` method will handle all occurrences of two spaces in a given string, so we're not looping (and re-allocating a whole string) for every instance of paired spaces in the string. One new allocation will handle all of them. We only re-run the loop when there were 3 or more spaces together, which is likely to be a rarer occurrence for many input sources. If you can show it becomes a problem for your data, then go write the state machine to push character by character into a new stringbuilder. – Joel Coehoorn Feb 19 '20 at 22:24
  • Yes, I now I got it. Thanks for your explanation. – pcbabu Feb 24 '20 at 21:24
30

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."
ScubaSteve
  • 7,724
  • 8
  • 52
  • 65
19
myString = Regex.Replace(myString, " {2,}", " ");
Jan Goyvaerts
  • 21,379
  • 7
  • 60
  • 72
12

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.

Nolonar
  • 5,962
  • 3
  • 36
  • 55
  • If you want to check if the character is whitespace, and not just a space [see my answer below](https://stackoverflow.com/a/58849324/8705563). – Reap Nov 14 '19 at 04:22
9

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, " ");
Aleks Andreev
  • 7,016
  • 8
  • 29
  • 37
somebody
  • 478
  • 10
  • 17
8

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.

ravish.hacker
  • 1,189
  • 14
  • 21
  • 1
    You have to make sure your string doesn't have "()" or ")(" in it. Or `"wel()come to london)("` becomes `"wel come to london"`. You could try using lots of brackets. So use `((((()))))` instead of `()` and `)))))(((((` instead of `)(`. It will still work. Still, if the string contains `((((()))))` or `)))))(((((`, this will fail. – nmit026 Jul 26 '17 at 22:18
8

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"

Stephen du Buis
  • 141
  • 1
  • 6
  • 2
    A word of caution : The use of split, while very simple to understand indeed, can have surprisingly negative performance impact. As many strings could be created, you'll have to watch your memory usage in case you handle large strings with this method. – Pac0 Jun 25 '18 at 15:26
8
// 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";
Jamshaid K.
  • 3,555
  • 1
  • 27
  • 42
Code
  • 679
  • 5
  • 9
5

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 (" ");
Jay Bazuzi
  • 45,157
  • 15
  • 111
  • 168
3

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 (" ");
Jay Bazuzi
  • 45,157
  • 15
  • 111
  • 168
3

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();
    }

}
The_Black_Smurf
  • 5,178
  • 14
  • 52
  • 78
3

Use the regex pattern

    [ ]+    #only space

   var text = Regex.Replace(inputString, @"[ ]+", " ");
M.Hassan
  • 10,282
  • 5
  • 65
  • 84
2

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.

Paul Easter
  • 631
  • 6
  • 5
2

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.
  • yes but you would only replace two whitespaces with one. This would not help X number of spaces – MGot90 Jul 26 '16 at 19:59
  • 2
    That While loop will take care of all that double spaces to be removed. – Learner1947 Mar 28 '17 at 16:55
  • In the loop you are replacing space characters but then with `Trim()` you are removing all removing leading and trailing _whitespace_ characters beyond just space. After fixing that with `Trim(' ')` there is then the problem that the question never asked for leading and trailing (white)spaces to be removed. After fixing _that_ by removing `Trim(' ')` entirely...you've now duplicated [this old answer](https://stackoverflow.com/a/206917/150605). Also, why post almost-C# code that's a few tweaks away from being made valid? – Lance U. Matthews Mar 29 '22 at 03:00
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.

Tom Gullen
  • 61,249
  • 84
  • 283
  • 456
1

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());
Ahmed Aljaff
  • 149
  • 2
  • 10
1

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 CondenseSpaces(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()
    {
        const string input = "     (five leading spaces)     (five internal spaces)     (five trailing spaces)     ";
        
        Console.WriteLine(" Input: \"{0}\"", input);
        Console.WriteLine("Output: \"{0}\"", StringExtension.CondenseSpaces(input));
    }
}

Executing this program produces the following output:

 Input: "     (five leading spaces)     (five internal spaces)     (five trailing spaces)     "
Output: " (five leading spaces) (five internal spaces) (five trailing spaces) "
Patrick Artner
  • 50,409
  • 9
  • 43
  • 69
  • 1
    This is, at first glance, a good and short and straightforward usage of `Aggregate()`; however, there is a bug in it. Testing `acc.Length > 0` clearly prevents an `IndexOutOfRange` exception for the `acc[acc.Length-1] != ' '` condition that follows, but this prevents _leading_ space characters from ever being emitted because `acc` is empty at that point. I have [corrected this](https://dotnetfiddle.net/CxydqZ) to `acc.Length == 0 || acc[acc.Length - 1] != ' '` and also expanded the sample code to demonstrate that single and multiple consecutive spaces throughout `s` are handled correctly. – Lance U. Matthews Mar 29 '22 at 01:19
  • 1
    One optimization you might make is to initialize `acc` with `new StringBuilder(s.Length)` since the longest the result `string` will be — when no replacements are made because `s` contains no runs of consecutive space characters — is the same length as the input `string`. Also, I'd suggest a method name like `CollapseSpaces()` or `CondenseSpaces()` to more accurately describe what it's doing; "strip" sounds like it's removing _all_ spaces. – Lance U. Matthews Mar 29 '22 at 01:31
  • @LanceU.Matthews thanks for reading and fixing, you are right. fixed the name. – Patrick Artner Mar 29 '22 at 05:18
1

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();
}
Reap
  • 1,047
  • 13
  • 16
  • Thanks, this helped me out. Small error: `strValue` should probably be `input`. Also, `IsWhiteSpace` includes line breaking characters. You probably don't want to merge multiple line breaks, if only for the fact it will behave differently based on your environment (`\r\n` vs `\n`). In this case check for 'CharUnicodeInfo.GetUnicodeCategory(c) == UnicodeCategory.SpaceSeparator'. – Oliver Schimmer Jul 13 '20 at 15:57
  • @OliverSchimmer that's right, thanks for the correction. The added unicode character info is a great addition. Feel free to make an edit! :) – Reap Jul 13 '20 at 16:31
  • Isn't this a rewrite of this answer? https://stackoverflow.com/a/33817748/56621 – Alex from Jitbit Jul 15 '20 at 15:30
  • @AlexfromJitbit, it's actually a modification of [my answer](https://stackoverflow.com/a/16776096/1169228), which predates that other answer by about 2.5 years. – Nolonar Jan 05 '22 at 22:18
  • @Nolonar yes, and I acknowledge that in my answer, hope thats ok – Alex from Jitbit Jan 07 '22 at 17:17
  • @AlexfromJitbit, sorry I misunderstood your comment. Everything's fine. – Nolonar Jan 07 '22 at 17:37
1

How about going rogue?

public static string MinimizeWhiteSpace(
    this string _this)
    {
        if (_this != null)
        {
            var returned = new StringBuilder();
            var inWhiteSpace = false;
            var length = _this.Length;
            for (int i = 0; i < length; i++)
            {
                var character = _this[i];
                if (char.IsWhiteSpace(character))
                {
                    if (!inWhiteSpace)
                    {
                        inWhiteSpace = true;
                        returned.Append(' ');
                    }
                }
                else
                {
                    inWhiteSpace = false;
                    returned.Append(character);
                }
            }
            return returned.ToString();
        }
        else
        {
            return null;
        }
    }
Demetris Leptos
  • 1,560
  • 11
  • 12
0

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 " ) );
onedaywhen
  • 55,269
  • 12
  • 100
  • 138
0

You can create a StringsExtensions file with a method like RemoveDoubleSpaces().

StringsExtensions.cs

public static string RemoveDoubleSpaces(this string value)  
{
  Regex regex = new Regex("[ ]{2,}", RegexOptions.None);
  value = regex.Replace(value, " ");

  // this removes space at the end of the value (like "demo ")
  // and space at the start of the value (like " hi")
  value = value.Trim(' ');

  return value;
}

And then you can use it like this:

string stringInput =" hi here     is  a demo ";

string stringCleaned = stringInput.RemoveDoubleSpaces();
Vasilis Plavos
  • 230
  • 2
  • 8
  • 2
    This is very inefficient. If the input contains 8 consecutive spaces then the first loop will run 3 times. The `StartsWith` in the first will have to search the whole string to get a `false` and if the string is large then that could take time. The second and third loops are unnecessary, the first loop means there can be at most one initial space and at most one final space. – AdrianHHH Feb 21 '22 at 11:27
  • Thanks for the comments @AdrianHHH . I make some quick improvements based on your tips. I will check it in a deeper stage for optimization once I will have some free time. Bests – Vasilis Plavos Feb 22 '22 at 08:36
  • The assignment `value = value.Replace(" ", " ");` allocates a new string on the heap to hold the result of the replace, the old string is then waiting to be garbage collected. If the initial input has 32 consecutive spaces then the loop will run 5 times, meaning that there will be 5 allocations of new strings and 5 old strings freed and ready for garbage collection. The final two modifications (for the leading and trailing space) will also allocate new strings and free old strings, if executed. – AdrianHHH Feb 22 '22 at 10:08
  • As a learning exercise I suggest you create a program to benchmark the various methods shown in the many answers to this question. Look for both execution time and memory (heap) usage. It might be nice to write that up as a new answer here. (Have a look at "BenchmarkDotNet".) – AdrianHHH Feb 22 '22 at 10:16
  • @AdrianHHH thanks for your comments. Memory is important but "easy to read/follow code" is more important to me. At the project I emplement it, there is no negative impact to the results, because of this I preffer to keep it as it is and focus on next features. I will check BenchmarkDotNet in any case. – Vasilis Plavos Feb 22 '22 at 12:10
  • 1
    It's one thing — and not at all a bad thing — to leave good code unoptimized in favor of clarity. Even at a glance, though, this is just needlessly inefficient code. Internally, both `Contains()` and `Replace()` must use `IndexOf()` (or something like it) to locate the specified `string`, so what you're saying is "scan for the specified string to see if it needs to be replaced, which, in turn, requires scanning for it _again_." This is analogous to `if (dict.ContainsKey(key)) value = dict[key];` instead of `found = dict.TryGetValue(key, out value);`. If a one-size-fits-most (cont.) – Lance U. Matthews Mar 29 '22 at 02:36
  • 1
    (cont.) solution makes the code too hard to read or comprehend then that's where _comments_, not BCL-method-calls-as-self-documentation, should be used to describe what's going on. As for what you're doing with the `*sWith()` calls, that can be replaced with `value = value.TrimEnd(' ').TrimStart(' ');` or, simply, `value = value.Trim(' ');`, but then removing lone leading or trailing spaces isn't relevant to this question, anyways. If nothing else, there already are several answers that use `string.Replace()`, and this one is adding [nothing new](https://stackoverflow.com/a/206917/150605). – Lance U. Matthews Mar 29 '22 at 02:36
  • Thanks for the comments @LanceU.Matthews . I will implement as many of your suggestions as I find useful. About the link you sent the difference is more at the String Extension thing and also at the trim. Bests – Vasilis Plavos Mar 30 '22 at 07:34
  • 1
    Recent changes to this answer mean it is extremely similar to many of the other answers and so it now adds nothing new to the question. – AdrianHHH Mar 30 '22 at 07:48
  • 1
    Trimming leading/trailing spaces wasn't part of the question, though, and the extension method is syntactic sugar; a reader can trivially incorporate those into their code, if needed. Ignoring those negligible changes, you've now duplicated [**the accepted answer**](https://stackoverflow.com/a/206720/150605), [this answer](https://stackoverflow.com/a/206799/150605), and two others that use the equivalent pattern `" {2,}"`. I will echo @AdrianHHH's comment and say that this answer is not adding any _new, useful_ information and is, thus, clutter on a question that already has too much of it. – Lance U. Matthews Mar 30 '22 at 08:58
-1

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.

Giedrius
  • 8,430
  • 6
  • 50
  • 91
  • I think this is the answer to a different question. Only spaces — not tabs or newlines or "mix of whitespace characters" — were mentioned in this question, so while this may be good analysis I don't see how this information is relevant here. – Lance U. Matthews Mar 29 '22 at 00:48
  • Downvotes indicate content that is "not useful" (however the voter chooses to define that) and pushes it down relative to other answers; I exercised mine because this answer, in my opinion, does not provide information that is relevant or useful to the question _as asked_ and, thus, is one more answer to look through — a distraction — when trying to find one that does focus on the posed problem. As I indicated, I don't think this is a bad answer in its own right, I just don't think it belongs _here_; I'd be surprised if there isn't at least one C# merge-adjacent-whitespace Q somewhere on SO. – Lance U. Matthews Mar 30 '22 at 00:09
-1

The following code remove all the multiple spaces into a single space

    public string RemoveMultipleSpacesToSingle(string str)
    {
        string text = str;
        do
        {
            //text = text.Replace("  ", " ");
            text = Regex.Replace(text, @"\s+", " ");
        } while (text.Contains("  "));
        return text;
    }
Bibin Gangadharan
  • 1,393
  • 12
  • 13
  • Why do you need the loop? Do you not trust `Regex.Replace()` to work the first time? Also, since performing the replace only really does anything when a character occurs _two or more_ times in a row, that's what you should match: `\s{2,}`. Most importantly, though, this does not do what the method name suggests or this question asked: `\s` matches not just a space but _any whitespace_ character. – Lance U. Matthews Mar 28 '22 at 10:21