问题:在一篇文章中一个匹配日期yyyy-MM-dd 的程序。
显然一个日期对应Java中的正则表达式
((\\d{4})-(\\d{2})-(\\d{2}))
然而,这样的正则表达式实现方式在处理如下输入数据时,无法提取出重叠的匹配
2000-03-2401-02-2014-03-2014-02-03
结果
2000-03-24 2014-03-20
这是由于第一个匹配消耗了其所在的所有字符的缘故,后续匹配将无法使用这些字符。这是我们需要使用(?=((\\d{4})-(\\d{2})-(\\d{2}))). 正则表达式。
其中(?=X) 这个语法匹配一个“位置”,这个位置向后可以完全匹配正则表达式X。(\\d{4})-(\\d{2})-(\\d{2}) 是之前用于匹配日期的正则表达式,. 用于匹配单个字符。整个正则表达式语义为“匹配一个可以匹配日期字符串的位置及其后的一个字符”。
而原来的年月日信息可以通过groups() 函数得到——
int year = Integer.parseInt(m.group(2)); int month = Integer.parseInt(m.group(3)); int days = Integer.parseInt(m.group(4));
对应的整个程序为——
import java.util.*; import java.util.regex.*; import java.io.*; class Main { static public void main(String args[]) throws FileNotFoundException,IOException { //BufferedReader fin = new BufferedReader(new InputStreamReader(new FileInputStream("input.txt"))); BufferedReader fin = new BufferedReader(new InputStreamReader(System.in)); char _text[] = new char[1050]; fin.read(_text,0,1050); String text = new String(_text); Pattern p = Pattern.compile("(?=((\\d{4})-(\\d{2})-(\\d{2})))."); Matcher m = p.matcher(text); boolean flag = false; while (m.find()) { int year = Integer.parseInt(m.group(2)); int month = Integer.parseInt(m.group(3)); int days = Integer.parseInt(m.group(4)); if (year < 1990 || year>=2018) continue; if (days <= 0) continue; if (month < 1 || month > 12) continue; if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) if (days > 31) continue; if (month == 4 || month == 6 || month == 9 || month == 11) if (days > 30) continue; if (month == 2) if (days > 28) continue; System.out.println(m.group(1)); flag = true; } if (!flag) System.out.println("NotMatch"); } };