1

入力日付の形式を把握するために正規表現を使用しています。これは私が使用しているパターンの1つです

    ^((18[5-9]|19[0-9]|20[0-9])\\d)(0?[1-9]|1[012])(0?[1-9]|[12][0-9]|3[01])$

そのため、制約は 1850 から 2099 の間の年を持つことです。たとえば、この文字列を日付 20011212 として渡すと、年、月、日を抽出するときに次のようになります。年: 2001、月: 200、日:12. 理由はありますか?

    pattern = Pattern.compile(PATTERN);
    matcher = pattern.matcher(dateString);
    if (matcher.matches()){
       matcher.reset();
       if (matcher.find()){
          Integer.parseInt(matcher.group(1));
          Integer.parseInt(matcher.group(2));
          Integer.parseInt(matcher.group(3));
       }
    }

コードは単純化されていますが、この単純化されたバージョンでも、誤った結果が返されます。提案/解決策をありがとう。

4

4 に答える 4

4

正規表現では、内部に入れるものはすべて(...)キャプチャ グループです。1 年に 2 つのグループがあり、どちらもキャプチャ グループです。

group(1) = ((18[5-9]|19[0-9]|20[0-9])\\d)
group(2) = (18[5-9]|19[0-9]|20[0-9])
group(3) = (0?[1-9]|1[012])
group(4) = (0?[1-9]|[12][0-9]|3[01])

次のように非キャプチャ ブロックを使用することもできます。(?:...)

したがって、パターンは次のようになります。

^((?:18[5-9]|19[0-9]|20[0-9])\\d)(0?[1-9]|1[012])(0?[1-9]|[12][0-9]|3[01])$
于 2012-10-25T09:27:48.310 に答える
4

2 番目のグループは年の上 3 桁であり、非キャプチャ グループを使用します。

^((?:18[5-9]|19[0-9]|20[0-9])\\d)(0?[1-9]|1[012])(0?[1-9]|[12][0-9]|3[01])$
于 2012-10-25T09:28:30.460 に答える
2

正規表現を に変更します^(18[5-9]\\d|19[0-9]\\d|20[0-9]\\d)(0?[1-9]|1[012])(0?[1-9]|[12][0-9]|3[01])$。2 番目の一致するグループを作成した年の最初の 3 桁の周りに括弧が多すぎます。

于 2012-10-25T09:29:17.453 に答える
1

これは、年の正規表現内にキャプチャ グループ (括弧のペア) があるためです。次のいずれかを実行できます。

  • 左括弧を数えて、正しいものを選択してください。将来正規表現を変更する場合、維持するのは困難です。
  • 名前付きグループを使用します。すべての正規表現フレーバーがこれをサポートしているわけではありません。Javaはそうでないものの1つだと思います。
  • 非キャプチャ グループを使用します。

非キャプチャ グループは?:、グループの先頭で次のように示されます。

^((?:18[5-9]|19[0-9]|20[0-9])\\d)(0?[1-9]|1[012])(0?[1-9]|[12][0-9]|3[01])$
   ^^--- here

ルックアラウンド ( (?= ... )、...) も非キャプチャであることに注意してください。

于 2012-10-25T09:29:52.613 に答える