Как написать регулярное выражение для разделения строки запятыми, за некоторыми исключениями? - PullRequest
2 голосов
/ 16 ноября 2009

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

rp { av 100, re 3, 52 }

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

rp { values, values values }

что я не хочу, чтобы это поймать. Это может быть рекурсивно.


Строка для оценки:

rp { av 100, re 3, rp { value 1, value 2, value 3 }, 52 }

Желаемое совпадение:

av 100
re 3
rp { value 1, value 2, value 3 }
52

1 Ответ

2 голосов
/ 16 ноября 2009

Мне не ясно, представляет ли этот пример потенциальное бесконечное вложение этих групп в стиле JSON или только один уровень вложения.

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

(Обратите внимание, я не писал это с IDE; концепция должна быть правильной, но синтаксические ошибки не могут быть гарантированы в настоящее время. Извинения)

string pattern = @"(?<key>)[A-Z]+)\s(?<value>({.+?}|[^{},]+))";

List<string[]> results = new List<string[]>(); //probably not best data structure

MatchCollection matches = Regex.Matches(input, pattern, RegexOptions.SingleLine | RegexOptions.IgnoreCase);
foreach(Match match in matches)
{
    if(match.Success)
    {
        results.Add(new string[] {
            match.Groups["key"].Value,
            match.Groups["value"].Value
        });
    }
}

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

string pattern = @"(?<key>)[A-Z]+)\s({(?<nested>.+?)}|(?<simple>[^{},]+))";

И для каждого совпадения, в котором вложенное значение имеет значение, выполните ту же процедуру для этого значения:

void Deserialize(string input, List<string[]> values)
{
    MatchCollection matches = Regex.Matches(input, pattern, RegexOptions.SingleLine | RegexOptions.IgnoreCase);
    foreach(Match match in matches)
    {
        if(match.Success)
        {
            if(match.Groups["nested"].Success && !string.IsNullOrEmpty(match.Groups["nested"].Value))
            {
                Deserialize(match.Groups["nested"].Value, values);
            }
            else
            {
                values.Add(new string[] {
                    match.Groups["key"].Value,
                    match.Groups["simple"].Value
                });
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...