C # Удаление символов-разделителей из строк в кавычках - PullRequest
5 голосов
/ 18 ноября 2010

Я пишу программу, которая должна удалять символы-разделители из строк в кавычках в текстовых файлах.

Например:

"Hello, my name is world"

Должно быть:

"Hello my name is world"

Поначалу это звучит довольно легко (я думал, что так и будет), но вам нужно определить, когда начинается кавычка, когда заканчивается кавычка, а затем искать в этой конкретной строке символы-разделители.Как?

Я экспериментировал с некоторыми регулярными выражениями, но я просто запутываюсь!

Есть идеи?Даже просто что-то, чтобы заставить мяч катиться, я просто в тупике.

Ответы [ 8 ]

4 голосов
/ 18 ноября 2010
string pattern = "\"([^\"]+)\"";
value = Regex.Match(textToSearch, pattern).Value;

string[] removalCharacters = {",",";"}; //or any other characters
foreach (string character in removalCharacters)
{
    value = value.Replace(character, "");
}
2 голосов
/ 18 ноября 2010

Используя шаблон регулярного выражения с прогнозом, шаблон будет: "\"(?=[^\"]+,)[^\"]+\""

\" соответствует открывающей двойной кавычке. Предварительный просмотр (?=[^\"]+,) попытается сопоставить запятую в цитируемом тексте. Затем мы сопоставляем остальную часть строки, если она не является двойной кавычкой [^\"]+, затем мы сопоставляем закрывающую двойную кавычку \".

Использование Regex.Replace позволяет компактно изменить результат и удалить ненужные запятые.

string input = "\"Hello, my name, is world\"";
string pattern = "\"(?=[^\"]+,)[^\"]+\"";
string result = Regex.Replace(input, pattern, m => m.Value.Replace(",", ""));
Console.WriteLine(result);
2 голосов
/ 18 ноября 2010

почему бы не попробовать и сделать это с Linq?

var x = @" this is a great whatever ""Hello, my name is world"" and all that";

var result = string.Join(@"""", x.Split('"').
Select((val, index) => index%2 == 1 ? 
val.Replace(",", "") : val).ToArray());
1 голос
/ 18 ноября 2010

То, что вы хотите написать, называется «лексером» (или, альтернативно, «токенизатором»), который читает входной символ за символом и разбивает его на токены. Так обычно работает синтаксический анализ в компиляторе (как первый шаг). Лексер разбивает текст на поток токенов (строковый литерал, идентификатор, "(" и т. Д.). Затем анализатор берет эти токены и использует их для создания дерева разбора.

В вашем случае вам нужен только лексер. У вас будет 2 типа токенов: «строки в кавычках» и «все остальное».

Тогда вам просто нужно написать код, чтобы разбить входные данные на токены. По умолчанию что-то является токеном «все остальное». Строковый маркер начинается, когда вы видите «, и заканчивается, когда вы видите следующее». Если вы читаете исходный код, вам, возможно, придется иметь дело с такими вещами, как \ "или" "в качестве особых случаев.

Как только вы это сделаете, вы можете просто выполнить итерацию по токенам и выполнить любую необходимую обработку для "строковых" токенов.

0 голосов
/ 18 ноября 2010

Хорошо, это немного странно, но работает.

Итак, сначала вы разбили свою строку на части, основываясь на символе ":

string msg = "this string should have a comma here,\"but, there should be no comma in this bit\", and there should be a comma back at that and";

var parts = msg.Split('"');

тогда вам нужно соединить строку обратно вместе с символом ", после удаления каждой запятой в каждой другой части:

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

Функция удаления выглядит следующим образом:

IEnumerable<string> RemoveCommaFromEveryOther(IEnumerable<string> parts)
{
    using (var partenum = parts.GetEnumerator())
    {
        bool replace = false;
        while (partenum.MoveNext())
        {
            if(replace)
            {
                yield return partenum.Current.Replace(",","");
                replace = false;
            }
            else
            {
                yield return partenum.Current;
                replace = true;
            }
        }
    }
}

Требуется, чтобы вы включили директиву использования для System.Collections.Generic.

0 голосов
/ 18 ноября 2010

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

        protected virtual string[] delimitCVSBuffer(string inputBuffer) {
        List<string> output       = new List<string>();
        bool insideQuotes         = false;
        StringBuilder fieldBuffer = new StringBuilder();
        foreach (char c in inputBuffer) {
            if (c == FieldDelimiter && !insideQuotes) {
                output.Add(fieldBuffer.Remove(0, 1).Remove(fieldBuffer.Length - 1, 1).ToString().Trim());
                fieldBuffer.Clear();
                continue;
            } else if (c == '\"')
                insideQuotes = !insideQuotes;
            fieldBuffer.Append(c);
        }
        output.Add(fieldBuffer.Remove(0, 1).Remove(fieldBuffer.Length - 1, 1).ToString().Trim());
        return output.ToArray();
    }
0 голосов
/ 18 ноября 2010

Итак, я думаю, у вас есть длинный текст с множеством цитат внутри? Я хотел бы сделать метод, который делает что-то вроде этого:

  1. Беги мыслью по струне, пока не встретишь первую "
  2. Затем возьмите подстроку до следующего ", и выполните str.Replace (", "," "), а также замените любые другие символы, которые вы хотите заменить.
  3. Тогда иди без замены, пока не встретишь следующее "и продолжай до конца.

EDIT

У меня просто получше идея. Как насчет этого:

  string mycompletestring = "This is a string\"containing, a quote\"and some more text";
  string[] splitstring = mycompletestring.Split('"');
  for (int i = 1; i < splitstring.Length; i += 2) {
    splitstring[i] = splitstring[i].Replace(",", "");
  }
  StringBuilder builder = new StringBuilder();
  foreach (string s in splitstring) {
    builder.Append(s + '"');
  }
  mycompletestring = builder.ToString().Substring(0, builder.ToString().Length - 1);

Я думаю, что должен быть лучший способ объединить строку в одну с "между ними в конце", но я не знаю лучших, поэтому не стесняйтесь предложить хороший метод здесь:)

0 голосов
/ 18 ноября 2010

Есть много способов сделать это: Лок на функции string.Split() и string.IndexOfAny()

Вы можете использовать string.Split (new char [] {',', ''}, StringSplitOption.RemoveEmptyEntries), чтобы вставить фразу в слова, а затем использовать класс StringBuilder, чтобы сложить слова вместе.

Вызов string.Replace("[char to remove goes here]"',"") несколько раз с каждым символом, которого вы хотите удалить, также будет работать.

EDIT:

Вызовите string.Split(new char[] {'\"'}, StringSplitOption.RemoveEmptyEntries), чтобы получить массив строк между кавычками ("), затем вызовите Replace для каждой из них, затем соедините строки вместе с StringBuilder.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...