简体   繁体   中英

regex for optional group

I'd like to parse the following sample string

foo :6

into two groups: Text and Number. The number group should be populated only if the character ":" precedes the number itself.

so:

foo 6 -> Text = "foo 6"
foo :6 -> Text = "foo", Number = "6"

The best I could come up with so far is

(?<Text>.+)(?=:(?<Number>\d+)h?)?

but that doesn't work because the first group greedily expands to the whole string.

Any suggestions?

If you really want to use a regex you can write quite a simple one, without lookarounds:

(?<Text>[^:]+):?(?<Number>\d*)

In my opinion, regexes should be as simple as possible; if you do not want spaces around the Text group I suggest you use match.Groups["Text"].Value.Strip() .

Note that if you are parsing a multiline string this pattern will not work because, as @OscarHermosilla mentioned below, [?:]+ will also match newlines. The fix is simple though, change it with [^:\\n]

You don't need any seperate function for stripping the trailing whitespaces

The below regex would capture all the characters into the named group Text except :\\d+ (ie; : followed by one or more numbers). If it finds a colon followed by numbers, then it starts capturing the number into the named group Number

^(?<Text>(?:(?!:\d+).)+(?=$|\s+:(?<Number>\d+)$))

DEMO

String input = "foo 6";
String input1 = "foo :6";
Regex rgx = new Regex(@"^(?<Text>(?:(?!:\d+).)+(?=$|\s+:(?<Number>\d+)$))");

foreach (Match m in rgx.Matches(input))
{
Console.WriteLine(m.Groups["Text"].Value);
}
foreach (Match m in rgx.Matches(input1))
{
Console.WriteLine(m.Groups["Text"].Value);
Console.WriteLine(m.Groups["Number"].Value);
}

Output:

foo 6
foo
6

IDEONE

You can repeat the group name text with an alternation. This way:

(?<Text>.+)\s+:(?<Number>\d)|(?<Text>.+)

DEMO

Based on the idea behind this post: Regex Pattern to Match, Excluding when... / Except between

您可以简单地使用split而不是regex:

"foo :6".Split(':');

You can try like:

(\D+)(?:\:(\d+))

or do a Regex.Split using this pattern:

(\s*\:\s*)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM