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 の内容は無視します。したがって、2 番目の括弧のセットがたまたま一致した場合、印刷物には表示されません。

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

|2 番目の正規表現は、2 つの選択肢を括弧で囲み、アンカーと を外側に残し、括弧を 1 セットだけ残して、結果が常にグループ #1 になるようにすることで問題を解決し^ます$

そして、それだけの価値があるため、{1}不要です。あなたは書くことができます:

^([1-9]|1[012])$
于 2012-10-16T00:15:03.807 に答える
2

代替演算子は、すべての正規表現演算子の中で最も優先順位が低くなります。

文字どおりに解釈された 2 つの正規表現の違いは次のとおりです。

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

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