在Java中的正则表达式:Pattern.compile("J.*\\d[0-35-9]-\\d\\d-\\d\\d")

3
我发现了一个Java正则表达式的代码,它让我感到困惑:
Pattern.compile( "J.*\\d[0-35-9]-\\d\\d-\\d\\d" );

需要编译的字符串是:

String string1 = "Jane's Birthday is 05-12-75\n" + "Dave's Birthday is 11-04-68\n" + "John's Birthday is 04-28-73\n" + "Joe's Birthday is 12-17-77";

什么是“

”的含义?
[0-35-9]

为什么有四个"\d"而不是三个?我假设生日中只有三个数字。

5个回答

3

\\d 的形式仅匹配数字,而不是数字。

因此,使用 \\d\\d 的模式将匹配两个连续的数字。

使用 \\d\\d-\\d\\d 的模式将匹配两个连续数字,一个字面上的 -,再加上两个连续的数字。

让我们来看看你的匹配以及原因。

Joe's Birthday is 12-17-77
                  ^          match a digit 0 to 9
                   ^         match any character of '0' to '3', '5' to '9'
                    ^        match a '-' literally
                     ^       match a digit 0 to 9
                      ^      match a digit 0 to 9
                       ^     match a '-' literally
                        ^    match a digit 0 to 9
                         ^   match a digit 0 to 9

[0-35-9]部分匹配任何介于0359之间的字符。

你整个正则表达式的解释:

J              'J'
.*              any character except \n (0 or more times)
\d              match a digit 0 to 9
 [0-35-9]       any character of: '0' to '3', '5' to '9'
   -            match a '-' literally
  \d            match a digit 0 to 9
  \d            match a digit 0 to 9 
   -            match a '-' literally
  \d            match a digit 0 to 9
  \d            match a digit 0 to 9

2

\\d 不匹配一个数字,它匹配的是一个数字字符。不同之处在于 \\d\\d 将匹配两个连续的数字字符。

[0-35-9] 匹配范围在 0-35-9 内的数字字符。

实际上这将匹配以下生日日期:10、11、12、01、02、03、05、06、07、08 或 09月份的出生日期。只要日和年份为两位数就可以,具体的值并不重要。这是一种非常冗长的方式来表示“找到任何一个不是四月(04)的生日日期”。


2
“[0-35-9]”的意思是你提供了一个由方括号包含的字符集,它指定了能够成功匹配给定输入字符串中单个字符的特定字符。因此,上述字符类将匹配如果被匹配的字符在0到3或5到9之间(包括0、3、5和9)。
关于为什么有四个“\d”而不是三个的问题,这是因为出生日期部分中包含了一个短横线(“-”),所以需要将其考虑在内。因此,“05-12-75”中共有八个字符,其中三个是数字,一个是短横线。
"\d"是一个预定义字符类,其中"\d"表示数字,"\d\d"表示两个连续的数字。因此,对于一个日期"xx-xx-xx-xx",我们会写成"\d\d-\d\d-\d\d-\d\d",其中"x"被认为是表示数字(0-9)的数字。

1
混淆是因为我们对数字的理解方式。在我们的数学眼中,中间部分看起来是一个单独的数字,即数字“35”。但实际上,它是两个数字,“3”和“5”。正如之前深入回答过的那样,这实际上是两个范围,从0到3的位数范围,以及从5到9的位数范围,从而消除了可能匹配的数字4。
至于“\d”的数量,实际上有5个而不是4个。第一个与要匹配月份的位数范围中的单个数字匹配(例如,十月为10,六月为06,因此两者都匹配,而四月为04则不匹配)。接下来的两个“\d”成对匹配成一天。最后两个成对匹配成一年。

0

这个答案是正确的,但我认为日期的前两位数字有误。

(月份应该是01-02-03-05-06-...-12)

\\d[0-35-9]

这个正则表达式提供了除了四月之外的所有月份,但它必须是0-12的间隔。

因此,正确的正则表达式应该如下所示:

(0[0-35-9]|1[0-2])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接