c # Самый быстрый способ удалить лишние пробелы - PullRequest
41 голосов
/ 22 июня 2011

Какой самый быстрый способ заменить лишние пробелы одним пробелом?
Например,

из

foo      bar 

до

foo bar

Ответы [ 25 ]

2 голосов
/ 29 декабря 2017

Этот кусок кода работает хорошо.Я не измерил производительность.

string text = "   hello    -  world,  here   we go  !!!    a  bc    ";
string.Join(" ", text.Split().Where(x => x != ""));
// Output
// "hello - world, here we go !!! a bc"
2 голосов
/ 01 июля 2016

Некоторые требования не ясны в этом вопросе, которые заслуживают некоторой мысли.

  1. Хотите ли вы одного начального или конечного пробела?
  2. Когда вы заменяете все пробелы одним символом, хотите ли вы, чтобы этот символ был согласованным? (то есть многие из этих решений заменили бы \ t \ t на \ t и '' на ''.

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

  public static string WhiteSpaceToSingleSpaces(string input)
  {
    if (input.Length < 2) 
        return input;

    StringBuilder sb = new StringBuilder();

    input = input.Trim();
    char lastChar = input[0];
    bool lastCharWhiteSpace = false;

    for (int i = 1; i < input.Length; i++)
    {
        bool whiteSpace = char.IsWhiteSpace(input[i]);

        //Skip duplicate whitespace characters
        if (whiteSpace && lastCharWhiteSpace)
            continue;

        //Replace all whitespace with a single space.
        if (whiteSpace)
            sb.Append(' ');
        else
            sb.Append(input[i]);

        //Keep track of the last character's whitespace status
        lastCharWhiteSpace = whiteSpace;
    }

    return sb.ToString();
  }
2 голосов
/ 22 июня 2011

попробуйте это:

System.Text.RegularExpressions.Regex.Replace(input, @"\s+", " ");
1 голос
/ 29 марта 2019

Я не знаю, если это самый быстрый способ, но я использую это, и это работает для меня:

    /// <summary>
    /// Remove all extra spaces and tabs between words in the specified string!
    /// </summary>
    /// <param name="str">The specified string.</param>
    public static string RemoveExtraSpaces(string str)
    {
        str = str.Trim();
        StringBuilder sb = new StringBuilder();
        bool space = false;
        foreach (char c in str)
        {
            if (char.IsWhiteSpace(c) || c == (char)9) { space = true; }
            else { if (space) { sb.Append(' '); }; sb.Append(c); space = false; };
        }
        return sb.ToString();
    }
1 голос
/ 16 февраля 2019

Я не очень знаком с C #, поэтому мой код не элегантный / самый эффективный. Я пришел сюда, чтобы найти ответ, который подходит для моего варианта использования, но я не смог его найти (или не смог его найти).

Для моего случая использования мне нужно было нормализовать все пробелы (WS: {space, tab, cr lf}) со следующими условиями:

  • WS может прийти в любой комбинации
  • Заменить последовательность WS на наиболее значимый WS
  • tab необходимо сохранить в некоторых случаях (файл, разделенный табуляцией, например, и в этом случае также необходимо сохранить повторные вкладки). Но в большинстве случаев они должны быть преобразованы в пробелы.

Итак, вот пример ввода и ожидаемый вывод (Отказ от ответственности: мой код тестируется только для этого примера)



        Every night    in my            dreams  I see you, I feel you
    That's how    I know you go on

Far across the  distance and            places between us   



You            have                 come                    to show you go on


для преобразования в

Every night in my dreams I see you, I feel you
That's how I know you go on
Far across the distance and places between us
You have come to show you go on

Вот мой код

using System;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main(string text)
    {
        bool preserveTabs = false;

        //[Step 1]: Clean up white spaces around the text
        text = text.Trim();
        //Console.Write("\nTrim\n======\n" + text);

        //[Step 2]: Reduce repeated spaces to single space. 
        text = Regex.Replace(text, @" +", " ");
        // Console.Write("\nNo repeated spaces\n======\n" + text);

        //[Step 3]: Hande Tab spaces. Tabs needs to treated with care because 
        //in some files tabs have special meaning (for eg Tab seperated files)
        if(preserveTabs)
        {
            text = Regex.Replace(text, @" *\t *", "\t");
        }
        else
        {
            text = Regex.Replace(text, @"[ \t]+", " ");
        }
        //Console.Write("\nTabs preserved\n======\n" + text);

        //[Step 4]: Reduce repeated new lines (and other white spaces around them)
                  //into a single new line.
        text = Regex.Replace(text, @"([\t ]*(\n)+[\t ]*)+", "\n");
        Console.Write("\nClean New Lines\n======\n" + text);    
    }
}

Смотрите этот код в действии здесь: https://dotnetfiddle.net/eupjIU

1 голос
/ 18 марта 2018

Для тех, кто просто хочет скопировать и продолжить:

    private string RemoveExcessiveWhitespace(string value)
    {
        if (value == null) { return null; }

        var builder = new StringBuilder();
        var ignoreWhitespace = false;
        foreach (var c in value)
        {
            if (!ignoreWhitespace || c != ' ')
            {
                builder.Append(c);
            }
            ignoreWhitespace = c == ' ';
        }
        return builder.ToString();
    }
1 голос
/ 05 октября 2017
public static string RemoveExtraSpaces(string input)
{
    input = input.Trim();
    string output = "";
    bool WasLastCharSpace = false;
    for (int i = 0; i < input.Length; i++)
    {
        if (input[i] == ' ' && WasLastCharSpace)
            continue;
        WasLastCharSpace = input[i] == ' ';
        output += input[i];
    }
    return output;
}
1 голос
/ 21 сентября 2017

Я знаю, что это действительно старый, но самый простой способ сжать пробел (заменить любой повторяющийся пробел символом с одним пробелом):

    public static string CompactWhitespace(string astring)
    {
        if (!string.IsNullOrEmpty(astring))
        {
            bool found = false;
            StringBuilder buff = new StringBuilder();

            foreach (char chr in astring.Trim())
            {
                if (char.IsWhiteSpace(chr))
                {
                    if (found)
                    {
                        continue;
                    }

                    found = true;
                    buff.Append(' ');
                }
                else
                {
                    if (found)
                    {
                        found = false;
                    }

                    buff.Append(chr);
                }
            }

            return buff.ToString();
        }

        return string.Empty;
    }
1 голос
/ 25 мая 2017

Я что-то здесь упускаю? Я придумал это:

// Input: "HELLO     BEAUTIFUL       WORLD!"
private string NormalizeWhitespace(string inputStr)
{
    // First split the string on the spaces but exclude the spaces themselves
    // Using the input string the length of the array will be 3. If the spaces
    // were not filtered out they would be included in the array
    var splitParts = inputStr.Split(' ').Where(x => x != "").ToArray();

   // Now iterate over the parts in the array and add them to the return
   // string. If the current part is not the last part, add a space after.
   for (int i = 0; i < splitParts.Count(); i++)
   {
        retVal += splitParts[i];
        if (i != splitParts.Count() - 1)
        {
            retVal += " ";
        }
   }
    return retVal;
}
// Would return "HELLO BEAUTIFUL WORLD!"

Я знаю, что здесь я создаю вторую строку, чтобы вернуть ее, а также создаю массив splitParts. Просто понял, что это довольно просто. Возможно, я не принимаю во внимание некоторые возможные сценарии.

1 голос
/ 20 октября 2016

Я только что взбил это, хотя еще не проверял это. Но я чувствовал, что это было элегантно и избегает регулярных выражений:

    /// <summary>
    /// Removes extra white space.
    /// </summary>
    /// <param name="s">
    /// The string
    /// </param>
    /// <returns>
    /// The string, with only single white-space groupings. 
    /// </returns>
    public static string RemoveExtraWhiteSpace(this string s)
    {
        if (s.Length == 0)
        {
            return string.Empty;
        }

        var stringBuilder = new StringBuilder();
        var whiteSpaceCount = 0;
        foreach (var character in s)
        {
            if (char.IsWhiteSpace(character))
            {
                whiteSpaceCount++;
            }
            else
            {
                whiteSpaceCount = 0;
            }

            if (whiteSpaceCount > 1)
            {
                continue;
            }

            stringBuilder.Append(character);
        }

        return stringBuilder.ToString();
    }
...