用于日期验证的正则表达式无法按预期工作

Regex for date-validation does not work as expected

我想验证用户输入的日期格式是否正确。我不知道如何在我的正则表达式中包含空格并接受两种不同类型的格式。

示例

以下是两种正确的格式:

  1. April 30, 2021
  2. 04/30/2021

这些应该由下面代码中的正则表达式匹配。

代码

public GeoCountDownTimer(String geoDate) {

    for (int i = 0; i < geoDate.length(); i++) {
        if (!String.valueOf(geoDate.charAt(i)).matches("[a-zA-Z0-9]")) {
            System.out.println("Incorrect formatting at: " + geoDate.charAt(i) + "\n");
        }
    }
}

am trying to exclude everything but a-z, 0-9 and spaces

这适用于任何包含 lettersdigitsspaces 和分号的字符串(您没有提到任何标点符号,但您的 ;例如 "January; 21 2022").

geoDate.matches("[\w\s;]+")

但是如果 geoDate 有一个固定的结构,我建议你改用这个条件:

geoDate.matches("\p{Alpha}{3,9}; \d{2} \d{4}")
上面用到的

字符类

\p{Alpha} - 一个字母字符

\w - 一个单词字符:[a-zA-Z_0-9]

\d - 一个数字:[0-9]

\s - 一个空白字符:[ \t\n\x0B\f\r]

{} - 是一个 量词 ,允许指定多个匹配项。

X{n,m} - X,至少n次但不超过m次

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/regex/Pattern.html

看起来像是日期验证和解析。 这可以使用不同的方法来解决:

  1. (high-level) date-parsing 函数(例如 java.text.DateFormat
  2. (low-level) regular-expressions (正则表达式)

我强烈推荐第一个,因为它更准确并且 well-tested,而且可以向同行传达意图。

使用 Java 的 date-formats

参见Parse a String to Date in Java, using SimpleDateFormat

String geoDate = "January; 21 2022":

SimpleDateFormat sdf = new SimpleDateFormat("MMMMM; dd yyyy");
try {
    Date date = sdf.parse(geoDate);
    System.out.println(date);
} catch (ParseException e) {
    e.printStackTrace();
}

注意:为了根据预期的区域设置解释 month-name(例如 US-en 的“一月”),您可以指定 Locale给构造函数:SimpleDateFormat(pattern, locale).

使用正则表达式

研究类似的问题,例如:

一个简单的正则表达式可能如下所示(仅匹配,现在 capture-groups 用于提取):

String geoDate = "January; 21 2022":

String regex_alphanum = "[a-zA-Z0-9 ]+";  // added a space
System.out.println(geoDate.matches(regex_alphanum)); // does not match because semicolon

String regex_alphanum_semicolon = "[a-zA-Z0-9 ;]+"; // added the semicolon
System.out.println(geoDate.matches(regex_alphanum_semicolon)); // matches

注意:添加到 character-range 的量词 (+) 至少匹配一次或多次出现。

缺点: 即使经过调整的正则表达式也可能匹配 "Mey; 99 0021",这不是有效日期或允许输入不存在的日期,例如 "February, 29 2022"(2022年不是闰年)