使用交替和分组构造

时间:2012-10-16 00:11:17

标签: c# regex

最初我想要一个正则表达式解析月份数字。起初我想出了以下正则表达式:

^([1-9]{1})|(1[012])$

它匹配任何正数,表示它匹配数字的高位数,即:

1 => 1
2 => 2
...
9 => 9
10=> 1
...
19=> 1
20=> 2
...

为什么会这样?我认为交替构造将使Regex选择左侧或右侧,而^&使其与整个字符串匹配。我错过了什么?

P.S。:我现在有一个正在运行的正则表达式(一个只匹配1到12的数字);它是:

^([1-9]{1}|1[012])$

我无法理解它为何如此有效......

这是我用来测试的代码:

Regex r = new Regex(@"^([1-9]{1})|(1[012])$");//^([1-9]{1}|1[012])$
for (int i = -5; i < 35; i++)
{
    Console.Write(i);
    Console.Write("\t");
    Match m = r.Match(i.ToString());
    if (m.Success)
        Console.WriteLine(m.Groups[0].Value);
    else
        Console.WriteLine("false");
}

2 个答案:

答案 0 :(得分:3)

阅读第一个正则表达式:

^([1-9]{1})      # match this
|                # ...OR...
(1[012])$        # match this

匹配字符串开头的数字1-9并将其存储在组#1中,或者在字符串末尾匹配10-12并将其存储在组#2中。

使用第一次成功匹配,因此当您与10匹配正则表达式匹配的^([1-9]{1})部分时。您可以看到20与此破坏的正则表达式匹配的原因。

此外,您只打印组#1的内容并忽略组#2。因此,如果第二组括号碰巧匹配,您将无法在打印输出中看到它。

if (m.Success)
    Console.WriteLine(m.Groups[0].Value);

你的第二个正则表达式通过用括号括起两个|替代词来修复问题,将^$锚点留在外面,只留下一组括号,以便得到结果总是在#1组。

对于它的价值,{1}是不必要的。你可以写:

^([1-9]|1[012])$

答案 1 :(得分:2)

The alternation operator has the lowest precedence of all regex operators.

字面解释的两个正则表达式之间的差异是:

( [BEGIN]([1-9]) )    OR    ( (1[012])[END] )

VS

[BEGIN] ( [1-9]    OR    1[012] ) [END]