C #: разбить строку на серии символов, чисел и строк с разделителями и обработать ее - PullRequest
0 голосов
/ 14 января 2011

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

Мне нужно разбить и обработать строку, содержащую любое количество следующих элементов, в любом порядке:

  • Символы (только строчные буквы)
  • Строки с разделителями в кавычках
  • Ints

Строки довольно странные (у меня нет контроляНад ними).Когда в строке более одного числа в строке, они разделяются запятой.Они должны быть обработаны в том же порядке, в котором они появились в исходной строке.

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

abc20a"Hi""OK"100,20b

С этой конкретной строкой результирующий стек вызовов будетвыглядит примерно так:

ProcessLetters( new[] { 'a', 'b', 'c' } );
ProcessInts( 20 );
ProcessLetters( 'a' );
ProcessStrings( new[] { "Hi", "OK" } );
ProcessInts( new[] { 100, 20 } );
ProcessLetters( 'b' );

Что я мог бы сделать, так это трактовать его как CSV, где вы строите токены, обрабатывая символы по одному, но я думаю, что это было бы проще сделать срегулярное выражение?

Ответы [ 3 ]

0 голосов
/ 14 января 2011

Вы можете использовать шаблон, содержащийся в этой строке:

@"(""[^""]*""|[a-z]|\d+)"

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

Если у ваших строк в кавычках могут быть экранированные кавычки (например, "Hi\"There\"""OK""Pilgrim"), то вы можете использовать этот шаблон для захвата и токенизации их вместе с остальной частью входной строки:

@"((?:""[^""\\]*(?:\\.[^""\\]*)*"")|[a-z]|\d+)"

Вот пример:

MatchCollection matches = Regex.Matches(@"abc20a""Hi\""There\""""""OK""""Pilgrim""100,20b", @"((?:""[^""\\]*(?:\\.[^""\\]*)*"")|[a-z]|\d+)");

foreach (Match match in matches)
{
    Console.WriteLine(match.Value);
}

Возвращает строковые токены:

a
b
c
20
a
"Hi\"There\""
"OK"
"Pilgrim"
100
20
b

Одна из приятных особенностей этого подхода заключается в том, что вы можете просто проверить первый символ, чтобы увидеть, в какой стек нужно поместить ваши элементы. Если первый символ является альфа-каналом, то он переходит в стек ProcessLetters, если символ числовой, затем он переходит в ProcessInts. Если первый символ - это кавычка, то он уходит в ProcessStrings после обрезания начальных и конечных кавычек и вызова Regex.Unescape(), чтобы отменить скрытые кавычки.

0 голосов
/ 14 января 2011
static void Main(string[] args)
{
    string test = @"abc20a""Hi""""OK""100,20b";
    string[] results = Regex.Split(test, @"(""[a-zA-Z]+""|\d+|[a-zA-Z]+)");

    foreach (string result in results)
    {
        if (!String.IsNullOrEmpty(result) && result != ",")
        {
            Console.WriteLine("result: " + result);
        }
    }
    Console.ReadLine();
}
0 голосов
/ 14 января 2011

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

/[a-z]|[0-9]+|"[^"]"/

Могут ли ваши строки содержать экранированные кавычки?

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