为什么正则表达式不匹配没有边界匹配器“行首”?

时间:2012-04-04 07:08:43

标签: java regex pattern-matching

在Java的正则表达式中有一些我不理解的东西。我有以下字符串(我需要“到日期”):

From Date :01/11/2011 To Date :30/11/2011;;;;;;;;;;;;;

我认为以下正则表达式(在Perl中)会匹配。

to\\s+date\\s*?:\\s*?([0-9]{2}[\\./][0-9]{2}[\\./][0-9]{2,4})

在Java中,此模式不匹配。但如果我在前面和末尾添加一个.+就行了 所以这个模式适用于Java:

Pattern p = Pattern.compile(".+to\\s+date\\s*?:\\s*?([0-9]{2}[\\./][0-9]{2}[\\./][0-9]{2,4}).+", Pattern.CASE_INSENSITIVE);

我不明白:我很清楚,如果我在末尾添加^(行的开头)和$,那么第一个模式在Java中是不匹配的这条线。这意味着,模式必须匹配整条线。但是如果没有这个,第一个模式应该实际匹配,因为如果我没有在前面和末尾设置分隔符,为什么模式关心超出此模式范围的字符串数据呢?这对我来说不合逻辑。在我看来,第一个模式的行为类似于String类的“contains”方法。我认为在Perl中也是如此。

2 个答案:

答案 0 :(得分:6)

在Java中,matches()验证整个字符串。您的输入可能包含换行符(不会被.+匹配)。

请改为尝试:

Pattern p = Pattern.compile(".+to\\s+date\\s*?:\\s*?([0-9]{2}[\\./][0-9]{2}[\\./][0-9]{2,4}).+", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher("... \n From Date :01/11/2011 To Date :30/11/2011;;;;;;;;;;;;; \n ...");

System.out.println(m.matches()); // prints false

if(m.find()) {
  System.out.println(m.group(1)); // prints 30/11/2011
}

使用find()时,您可以从模式中删除.+

Pattern.compile("to\\s+date\\s*?:\\s*?([0-9]{2}[./][0-9]{2}[./][0-9]{2,4})", Pattern.CASE_INSENSITIVE);

(无需转义字符类中的.,顺便说一句)

答案 1 :(得分:0)

我认为来自不同问题的答案也会回答您的问题:Why do regular expressions in Java and Perl act differently?