您确实非常接近答案:只需将匹配第二个字符作为可选字符即可。
String s = "1a2b3c4d5";System.out.println(s.replaceAll(".(.)?", "$1"));// prints "abcd"之所以有效,是因为:
- 正则表达式默认是贪婪的,如果有则使用第二个字符
- 当输入的长度为奇数时,第二个字符将在最后一次替换时不存在,但您仍将匹配一个字符(即输入中的最后一个字符)
- 即使组不匹配,您仍然可以使用反向引用进行替换
- 它将替换为空字符串,而不是
"null"
- 这与不同
Matcher.group(int)
,后者会null
为失败的组返回
- 它将替换为空字符串,而不是
参考文献
- regular-expressions.info/可选
仔细看看第一部分
让我们仔细看看作业的第一部分:
String s = "1a2b3c4d5";System.out.println(s.replaceAll("(.).", "$1"));// prints "12345"在这里,您不必使用
?第二个字符,但是它“有效”,因为即使您不匹配最后一个字符, 也不必使用!
由于问题说明,最后一个字符可以保持不匹配,无法替换的状态。
现在假设我们要删除索引为1,3,5 …的字符,并将索引为0,2,4 …的字符放在方括号中。
String s = "1a2b3c4d5";System.out.println(s.replaceAll("(.).", "($1)"));// prints "(1)(2)(3)(4)5"哈!现在,您在使用奇数长度输入时遇到了完全相同的问题!您无法将最后一个字符与您的正则表达式匹配,因为您的正则表达式需要两个字符,但最后一个字符用于奇数长度输入!
同样,解决方案是使匹配第二个char为可选:
String s = "1a2b3c4d5";System.out.println(s.replaceAll("(.).?", "($1)"));// prints "(1)(2)(3)(4)(5)"


