Java中String的matches方法设下的坑
缘由:最近在工作中需要用正则匹配一个字符串最后面的几个字符, 例如,需要字符串后面是一个横杠 "-"加一个数字, 即型如 “-9”.
第一步:确认正则表达式
正则匹配在字符串最后面的短杆加一个数字, 正则表达式为:-\d$
测试例子:
/*
* 预期通过正则表达式将匹配到示例字符串中的"-1"字符.
*/
String testStr = "Test-20190805-1";
String regex = "-\\d$";
第二步:匹配出现错误
然而在Java代码中,直接调用String类的matches()方法时,却没有得到期望的真值.
String testStr = "Test-20190805-1";
String regex = "-\\d$";
boolean matched = testStr.matches(regex);//这里得到的matched值为false
第三步:分析原因
这里我们使用的正则表达式确实是表示"在字符串末尾的短杆加一个数字",问题出在matches方法上.
这里String的matches方法和Pattern中的matches方法都是指:当前这个字符串是否匹配表达式,而不匹配子串的情况.
也就是需要我们的正则式是完全匹配当前字符串,那么matches方法才会是返回true值.
而显然, 这里我们使用的正则表达式"-\d$" 仅匹配到了字符串的后两位子串,而没有匹配到前面那一部分的"Test-20190805", 因此没有按照我们的期望来执行了.
第四步:解决方案
第一种方案:将原正则式改写为匹配整个字符串的正则式
既然matches方法是匹配完整的字符串,那么我们将正则式补完也就可以匹配到了,如下:
String testStr = "Test-20190805-1";
String regex = ".*-\\d"; //增加了".*"补完正则表达式,表示在短杆与数字之前还有任意个字符
boolean matched = testStr.matches(regex);//这里得到的matched值为true
第二种方案:使用Matcher的find方法来匹配子串
如果不方便补完正则表达式,那么就不要使用matches方法,转而使用Matcher的find()方法.
Matcher的find方法将匹配字符串种的子串,有符合正则表达式的子串将放回为真.
String testStr = "Test-20190805-1";
Pattern p = Pattern.compile("-\\d$");
Matcher m = p.matcher(testStr);
boolean matched = m.find();//这里得到的matched值为true
但是这里需要注意的是,find方法有点类似于iterator方法,带有"游标"的效果. 也就是执行一次find方法后,将跳入下一次的匹配结果中去,如果字符串中没有第二个匹配的子串,这时将返回false了.
String testStr = "Test-20190805-1";
Pattern p = Pattern.compile("-\\d$");
Matcher m = p.matcher(testStr);
boolean firstFind = m.find();//第一次执行find,这里得到的值为true
boolean secondFind = m.find();//第二次执行find,这里得到的值为false