Как заменить несколько пробелов одним пробелом в C#?

Как я могу заменить несколько пробелов в строке только одним пробелом в C#?

пример:

1 2 3  4    5

будет:

1 2 3 4 5

21 ответов


RegexOptions options = RegexOptions.None;
Regex regex = new Regex("[ ]{2,}", options);     
tempo = regex.Replace(tempo, " ");

Мне нравится использовать:

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

Так как он будет ловить прогоны любого вида пробелов(например, вкладки, новые строки и т. д.) и заменить их одним пробелом.


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

Я думаю, что ответ Мэтта лучший, но я не думаю, что это правильно. Если вы хотите заменить новые строки, вы должны использовать:

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

это намного проще, чем все это:

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

другой подход, который использует LINQ:

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

Regex может быть довольно медленным даже с простыми задачами. Это создает метод расширения, который можно использовать с любого 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();
        }
    }

Он будет использоваться так:

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

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

для тех, кто не нравится Regex, вот метод, который использует 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();
    }

в моих тестах этот метод был в 16 раз быстрее в среднем с очень большим набором строк малого и среднего размера по сравнению со статическим скомпилированным регулярным выражением. По сравнению с нескомпилированных или метод regex, это должно быть еще быстрее.

имейте в виду, что он делает не удалить начальные и конечные пробелы, только несколько экземпляров таких.


вы можете просто сделать это в одно решение!

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

вы можете выбрать другие скобки (или даже другие символы), если хотите.


это более короткая версия, которая должна использоваться, только если вы делаете это только один раз, так как она создает новый экземпляр Regex класс каждый раз, когда он вызывается.

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

если вы не слишком знакомы с регулярными выражениями, то вот краткое объяснение:

на {2,} делает регулярное выражение для поиска символа, предшествующего ему, и находит подстроки между 2 и неограниченное время.
The .Replace(temp, " ") заменяет все совпадения в строке temp на a пространство.

если вы хотите использовать это несколько раз, вот лучший вариант, так как он создает регулярное выражение IL во время компиляции:

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

Consolodating другие ответы, за Джоэлом, и, надеюсь, слегка улучшив, как я иду:

вы можете сделать это с помощью Regex.Replace():

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

или 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 (" ");

нет регулярных выражений, нет Linq... удаляет ведущие и конечные пробелы, а также уменьшает любые встроенные несколько сегментов пространства до одного пространства

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

результат:"0 1 2 3 4 5"


Я знаю, что это довольно старый, но наткнулся на это, пытаясь выполнить почти то же самое. Нашел это решение в RegEx Buddy. Эта картина заменит все двойные космосы с одиночными космосами и также уравновесит ведущие и отставая космосы.

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

его немного трудно читать, так как мы имеем дело с пустым пространством, поэтому здесь он снова с "пробелами", замененными на "_".

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

в "(?m: "construct включает опцию" Multi-line". Я вообще хотелось бы включить все возможные варианты в сам шаблон, чтобы он был более самодостаточным.


Я только что написал новый Join что мне нравится, поэтому я подумал, что я отвечу, с ним:

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

одна из интересных вещей об этом заключается в том, что он работает с коллекциями, которые не являются строками, вызывая ToString() на элементах. Использование по-прежнему то же самое:

//...

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

Я могу удалить пробелы с этим

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

многие ответы обеспечивают правильный выход, но для тех, кто ищет лучшие выступления, я улучшил Nolanar это (что было лучшим ответом для производительности) примерно на 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();
    }

}

попробовать этот метод

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

используйте его так:

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

старый 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 " ) );

без использования регулярных выражений:

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

OK для использования на коротких строках, но будет плохо работать на длинных строках с большим количеством пробелов.


используйте шаблон regex

    [ ]+    #only space

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