Фильтрация строк, разделенных запятыми, в C#

#c# #.net #arrays #string #c#-2.0

#c# #.net #массивы #строка #c #-2.0

Вопрос:

У меня есть динамическое строковое значение, которое может содержать такие значения

 "Apple   ,Banana, , , ,  Mango  ,Strawberry  , " 
  

Я хотел бы отфильтровать эту строку следующим образом

 "Apple,Banana,Mango,Strawberry". 
  

Я пробовал использовать следующий код, и он работает.

Есть ли лучший подход для достижения того же в C # (.NET 2.0)?

 /// <summary>
/// Convert "Comma Separated String" to "Comma Separated String"
/// </summary>
/// <param name="strWithComma">String having values separated by comma</param>
/// <returns>String separated with comma</returns>
private String CommaSeparatedString(String strWithComma)
{
    String rtn = String.Empty;

    List<String> newList= new List<string>();

    if (String.IsNullOrEmpty(strWithComma))
    {
        return rtn;
    }

    String[] strArray = strWithComma.Split(",".ToCharArray());


    if (strArray == null || strArray.Length == 0)
    {
        return rtn;
    }

    String tmpStr = String.Empty;
    String separator=String.Empty;
    foreach (String s in strArray)
    {
        if (!String.IsNullOrEmpty(s))
        {
            tmpStr =s.Replace(Environment.NewLine, String.Empty);
            tmpStr = tmpStr.Trim();
            if (!String.IsNullOrEmpty(tmpStr))
            {
                newList.Add(tmpStr);
            }
        }
    }

    if (newList != null amp;amp; newList.Count > 0)
    {

        rtn = String.Join(",", newList.ToArray());
    }
    return rtn;

}
  

Комментарии:

1. Для codereview.stackexchange.com .

2. Может ли у вас быть несколько слов между запятыми?

3. @Rune, если в запятой есть несколько слов, я бы хотел сохранить его, поскольку он учитывает один пробел между словами. Хотя я не упоминал об этом в своем посте. Большое спасибо за разъяснения.

4. Вы говорите, что используете .NET 2.0, но какую версию C #? (C # 3.5 использует .NET 2.0)

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

Ответ №1:

вы также можете использовать регулярное выражение:

 string str = @"Apple   ,,Banana, , , ,  Mango  ,Strawberry  , ";
string result = Regex.Replace(str, @"(s*,s*) ", ",").TrimEnd(',');
  

Комментарии:

1. 1 для рабочего решения, даже для сценариев с несколькими словами и новой строкой

Ответ №2:

Я считаю, что следующее должно подействовать на any .СЕТЕВАЯ версия:

 string[] TrimAll( string[] input )
{
    var result = new List<string>();
    foreach( var s in input )
        result.Add( s.Trim() );
    }
    return result.ToArray();
}

var delimiters = new [] { ",", "t", Environment.NewLine };
string result = string.Join(",", TrimAll( input.Split( delimiters, StringSplitOptions.RemoveEmptyEntries ) ) );
  

Редактировать: обновлено для работы с пробелами, табуляциями и новой строкой.

Комментарии:

1. К сожалению StringSplitOptions.RemoveEmptyEntries , не удалит целые строки, состоящие только из пробелов.

2. Как насчет пробелов и перевода новой строки? Спасибо.

3. @Konamiman верно, но просто добавьте пробелы в массив разделителей, и это работает так же, как ваш ответ (с той же проблемой для допустимых пробелов)

4. @ANeves вы действительно нашли время, чтобы прочитать весь комментарий? предложенное konamimans решение имеет проблему в том, что оно не сохраняет пробелы между словами, как это делает это решение, даже если исправление ошибки, на которую указывает konamiman, все это (в более короткой версии) содержится в комментарии, на который вы тоже ссылаетесь, или я упускаю вашу точку зрения?

5. @RuneFS [Удалит.] Извините, вы правы, я неправильно понял. Заметка для себя, не занимайтесь серфингом ТАК, когда устали. 🙁

Ответ №3:

Предполагая, что ваши элементы не содержат пробелов:

 private String CommaSeparatedString(String strWithComma)
{
    string[] tokens = strWithComma
        .Replace(" ", "")
        .Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
    return string.Join(",", tokens);
}
  

Теперь я не уверен, принимает ли C # 2.0 new char[] {','} синтаксис. Если нет, вы можете определить массив где-нибудь еще (например, как закрытый член класса).

Комментарии:

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

Ответ №4:

Вот однострочный:

 var outputString = string.Join(",", inputString.Replace(" ", string.Empty).Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
  

Комментарии:

1. Не будет работать, когда между словами есть допустимые пробелы, и было бы чище и быстрее, если бы вы разделяли с помощью » » и «», если пробелы между словами не разрешены

2. В моем коде я также проверил наличие перевода новой строки. Будет ли этот код обрабатывать перевод новой строки?

3. @Rune FS, тогда это будет сложнее, чем исходное сообщение. Рассмотрим эту строку: "Apple ,Banana, , Pineapple Orange , , Mango ,Strawberry , " . Обратите , Pineapple Orange , внимание и на то, как неоднозначно расставлены пробелы. @Hoque, не могли бы вы при необходимости обновить свой вопрос?

4. @hoque нет, это также не позволит использовать пробел между словами

5. @AlexR. да, это так, но если вы прочитаете ответ OPs на вопрос о том, следует ли сохранять такие пробелы, он говорит: «Да, это должно быть сохранено», и исходный код сохраняет этот пробел

Ответ №5:

 Regex regex = new Regex(@"w(?:(?!,| ).)*");
            var items = regex.Matches("Apple ,Banana, , , , Mango ,Strawberry , ").Cast<Match>().Select(m => m.Value);
  

Версия .NET 2.0

 List<string> newList = new List<string>();

            Regex regex = new Regex(@"w(?:(?!,| ).)*");
            string str = "Apple ,Banana, , , , Mango ,Strawberry , ";
            MatchCollection matches = regex.Matches(str);
            foreach (Match match in matches)
            {
                newList.Add(match.Value);
            }
  

Комментарии:

1. Это работает… Конечно, вы бы поставили strWithComma в качестве первого аргумента в регулярном выражении. Соответствует (), а не буквальной строке, как я сделал для примера…

2. Распространяется ли это на удаление «перевода новой строки»?

3. ДА. Я только что попробовал это "Apple ,Banana, , , , Mango ,Strawberry , nOrange" , и все в порядке

4. Этот шаблон в основном w[^, ]* (единственное реальное отличие — новые строки). Если вам нужны пробелы в токенах, вы можете использовать [^s,][^,]*?(?=s*,|s*$) (вероятно, вы можете упростить это, это выглядит слишком много)

Ответ №6:

 var result = Regex.Replace(strWithComma, ", ", ",").TimEnd(',');
result = Regex.Replace(result, "s ", string.Empty);
  

Ответ №7:

Без регулярных выражений, без разбиений и объединений, обрезки и т. Д., O (n) раз. StringBuilder — очень хороший класс для работы со строками.

РЕДАКТИРОВАТЬ, если строка не заканчивается буквой, она добавит запятую. Таким образом, добавляется дополнительное обрезание (‘,’)

 string strWithComma = ",Apple   ,Banana, , , ,  Mango  ,Strawberry  , n John,";
var sb = new StringBuilder();
var addComma = false;
foreach (var c in strWithComma )
{         
  if (Char.IsLetter(c)) // you might want to allow the dash also: example Anne-Marie
  {
    addComma = true;
    sb.Append(c);         
  }
  else
  {         
    if (addComma)
    {
      addComma = false;
      sb.Append(','); 
    }
  }  
}
string rtn = sb.ToString().TrimEnd(',');
  

Комментарии:

1. Кажется интересным. Стоит попробовать.

Ответ №8:

Предупреждение этот метод будет применяться только для C # 3.0 или выше. Извините, ребята, недостаточно хорошо прочитали вопрос

Это будет работать, но это можно сделать намного проще, например:

 string input = "apple,banana,, n,testn, ,juice";

var parts = from part in input.Split(',')
            let trimmedPart = part.Replace("n", "")
            where !string.IsNullOrWhiteSpace(trimmedPart)
            select trimmedPart;

string result = string.Join(",", parts);