开发者

How to write regex to split a string by commas, with some exceptions?

开发者 https://www.devze.com 2022-12-11 06:53 出处:网络
I\'ve been learning regular expressions for the last few days and I\'ve been stumbled on this one. I would like to split a string by commas but with exceptions. Here\'s my string on what I want to val

I've been learning regular expressions for the last few days and I've been stumbled on this one. I would like to split a string by commas but with exceptions. Here's my string on what I want to validate:

rp { av 100, re 3, 52 }

which is basic comma delimited values inside of curly braces. Getting the values, I can do. But inside of each values, there could be another

rp { values, valu开发者_开发百科es values }

which I don't want it to catch. This can be recursive.


String to evaluate:

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

Desired match:

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


It's not clear to me if this example represents a potential infinite nesting of these JSON-esque groups, or just one level of nesting.

If only one level of nesting is possible, a straightforward Regex will do:

(Please note I did not write this with an IDE; the concept should be correct but syntax errors can't be guaranteed at the moment. Apologies)

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
        });
    }
}

If they can be nested many levels, you probably want to approach this recursively. That would necessitate splitting the value match into nested value and simple value:

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

And for each match where nested has a value, execute the same routine against that value:

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
                });
            }
        }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消