1

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

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

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

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

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

PS:我现在确实有一个有效的正则表达式(仅匹配从 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");
}
4

2 回答 2

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])$
于 2012-10-16T00:15:03.807 回答
2

交替运算符在所有正则表达式运算符中的优先级最低。

两个正则表达式之间的区别,字面解释,是这样的:

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

对比

[BEGIN] ( [1-9]    OR    1[012] ) [END]
于 2012-10-16T00:18:40.917 回答