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

在正则表达式中,您放入的所有内容(...)都是一个捕获组。一年中有两个组,它们都是捕获组:

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

第二组是年份的前三位,使用非捕获组:

^((?: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])$. 您在创建第二个匹配组的年份的前 3 位数字周围有太多括号。

于 2012-10-25T09:29:17.453 回答
1

这是因为您在 year 正则表达式中有一个捕获组(一对括号)。您可以:

  • 计算左括号并选择正确的括号。如果您将来要更改正则表达式,则很难维护。
  • 使用命名组。并非所有的正则表达式都支持这一点。我认为Java是其中之一。
  • 使用非捕获组。

非捕获组?:在组的开头表示为:

^((?: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 回答