Как мне преобразовать пробелы, кроме тех, что в кавычках, в запятые в C #? - PullRequest
2 голосов
/ 20 июня 2009

Предположим, у меня есть такая строка:

one two three "four five six" seven eight

и я хочу преобразовать это в:

one,two,three,"four five six",seven,eight

Какой самый простой способ сделать это в C #?

Ответы [ 8 ]

9 голосов
/ 20 июня 2009

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

public string SpaceToComma(string input) { 
  var builder = new System.Text.StringBuilder();
  var inQuotes = false;
  foreach ( var cur in input ) {
    switch ( cur ) { 
      case ' ':
         builder.Append(inQuotes ? cur : ',');
         break;
      case '"':
         inQuotes = !inQuotes;
         builder.Append(cur);
         break;
      default:
         builder.Append(cur);
         break;
    }
  }
  return builder.ToString();
}
2 голосов
/ 20 июня 2009
 static string Space2Comma(string s)
 {
    return string.Concat(s.Split('"').Select
        ((x, i) => i % 2 == 0 ? x.Replace(' ', ',') : '"' + x + '"').ToArray());
 }
0 голосов
/ 20 июня 2009

@ Мерада избил меня, но думаю, я все равно выложу:

static string Convert(string input)
{
    var slices = input
        .Split('"')
        .Select((s, i) => i % 2 != 0
            ? @"""" + s + @""""
            : s.Trim().Replace(' ', ','));

    return string.Join(",", slices.ToArray());
}

LINQ определено и протестировано :-) ... Для полного консольного приложения: http://pastebin.com/f23bac59b

0 голосов
/ 20 июня 2009

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

private String SpaceToComma(string input)
{
    String[] temp = input.Split(new Char[] { '"' }, StringSplitOptions.RemoveEmptyEntries);
    for (Int32 i = 0; i < temp.Length; i += 2)
    {
        temp[i] = temp[i].Trim().Replace(' ', ',');
    }
    return String.Join(",", temp);
}
0 голосов
/ 20 июня 2009

Это может быть излишним, но если вы считаете, что проблема может распространяться, например, необходимость деления на другие типы символов или наличие дополнительных правил, определяющих токен, вам следует рассмотреть возможность использования генератора синтаксического анализатора, такого как Коко или написание простого самостоятельно. Например, Coco / R создаст сгенерированный вами лексер и парсер из грамматики EBNF. Лексером будет DFA или конечный автомат, который представляет собой обобщенную форму кода, предоставленного JaredPar. Ваше определение грамматики для Coco / R будет выглядеть так:

CHARACTERS
alphanum = 'A'..'Z' + 'a'..'z' + '0'..'9'.

TOKENS
unit   = '"' {alphanum|' '} '"' | {alphanum}.

Затем созданный лексер будет сканировать и токанизировать ваш ввод соответственно.

0 голосов
/ 20 июня 2009

Вот более многократно используемая функция, которую я придумал:

private string ReplaceWithExceptions(string source, char charToReplace, 
    char replacementChar, char exceptionChar)
{
    bool ignoreReplacementChar = false;
    char[] sourceArray = source.ToCharArray();

    for (int i = 0; i < sourceArray.Length; i++)
    {
        if (sourceArray[i] == exceptionChar)
        {
            ignoreReplacementChar = !ignoreReplacementChar;
        }
        else
        {
            if (!ignoreReplacementChar)
            {
                if (sourceArray[i] == charToReplace)
                {
                    sourceArray[i] = replacementChar;
                }
            }
        }
    }

    return new string(sourceArray);
}

Использование:

string test = "one two three \"four five six\" seven eight";
System.Diagnostics.Debug.WriteLine(ReplaceWithExceptions(test, char.Parse(" "),
    char.Parse(","), char.Parse("\"")));
0 голосов
/ 20 июня 2009

Мое первое предположение - использовать уже созданный синтаксический анализатор и просто изменить символ разделителя и кавычки в соответствии с вашими потребностями (как и «соответственно»).

Похоже, это доступно вам в C #: http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser.aspx

Возможно, если вы изменили разделитель на "", он может удовлетворить ваши потребности для чтения в файле, и тогда это просто вопрос вызова String.Join () a для каждой строки.

0 голосов
/ 20 июня 2009

Я бы использовал для этого класс Regex.

Регулярные выражения могут быть использованы для сопоставления вашего ввода, разбить его на отдельные группы, которые вы можете затем собрать как угодно. Вы можете найти документацию по классам регулярных выражений здесь .

Regex rx = new Regex( "(\w)|([\"]\w+[\"])" );
MatchCollection matches = rx.Matches("first second \"third fourth fifth\" sixth");
string.Join( ", ", matches.Select( x => x.Value ).ToArray() );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...