Как мне преобразовать пробелы, кроме тех, что в кавычках, в запятые в C #?

2

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

one two three "four five six" seven eight

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

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

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

  • 0
    Вы действительно хотите, чтобы кавычки появлялись в конечном выводе? Когда они присутствуют, вы не можете просто разделить полученную строку запятыми, чтобы выполнить дальнейшую обработку каждого элемента.
  • 0
    @JeffK: для этого конкретного приложения «четыре пять шесть» считается одним элементом.
Показать ещё 2 комментария
Теги:
string

8 ответов

0
Лучший ответ

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

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("\"")));
9

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

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
 static string Space2Comma(string s)
 {
    return string.Concat(s.Split('"').Select
        ((x, i) => i % 2 == 0 ? x.Replace(' ', ',') : '"' + x + '"').ToArray());
 }
  • 0
    Дох ... Я собирался попробовать LINQ-ify, но ты побил меня этим :-)
0

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

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

@Mehrdad избил меня, но думаю, я все равно отправлю его:

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

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

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

0

Для этой цели я бы использовал класс Regex.

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

Regex rx = new Regex( "(\w)|([\"]\w+[\"])" );
MatchCollection matches = rx.Matches("first second \"third fourth fifth\" sixth");
string.Join( ", ", matches.Select( x => x.Value ).ToArray() );
  • 0
    Как вы можете использовать Regex для решения этой проблемы? В регулярных выражениях я не думаю, что был бы способ узнать, в цитате вы или нет ...
  • 0
    Regex в .NET поддерживает как упреждающее, так и парное исключение.
Показать ещё 4 комментария
0

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

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

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

Затем созданный лексер сканирует и упорядочивает ваш вход соответственно.

0

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню