使用Java regex删除字符串中的每个其他字符

我有这个家庭作业问题,我需要使用正则表达式来删除字符串中的每个其他字符.

一方面,我必须删除索引1,3,5上的字符,我已经做了如下:

String s = "1a2b3c4d5";
System.out.println(s.replaceAll("(.).","$1"));

这打印12345这是我想要的.基本上我一次匹配两个字符,并替换为第一个字符.我使用组捕获来做到这一点.

问题是,我在作业的第二部分遇到麻烦,我需要删除索引0,2,4的字符…

我做了以下工作:

String s = "1a2b3c4d5";
System.out.println(s.replaceAll(".(.)","$1"));

这打印abcd5,但正确的答案必须是abcd.如果输入的字符串长度是奇数,我的正则表达式是不正确的.如果是平均的,那么我的正则表达式工作正常.

我想我真的很接近答案,但我不知道如何解决这个问题.

解决方法

你确实非常接近答案:只需匹配第二个char可选.
String s = "1a2b3c4d5";
System.out.println(s.replaceAll(".(.)?","$1"));
// prints "abcd"

这是因为:

>正则表达式认是贪心,如果它在那里,它将占用第二个字符

>当输入的奇数长度时,第二个字符不会在最后一次替换,但您仍然会匹配一个字符(即输入中的最后一个字符)

>即使组无法匹配,您仍然可以使用反向引用替换

>它将替换为空字符串,而不是“null”
>这与Matcher.group(int)不同,它为失败的组返回null

参考

> regular-expressions.info/Optional

仔细看看第一部分

我们来仔细看看功课的第一部分:

String s = "1a2b3c4d5";
System.out.println(s.replaceAll("(.).","$1"));
// prints "12345"

这里你没有必要使用?对于第二个字符,但它“工作”,因为即使你不符合最后的字符,你没有必要!由于问题规范,最后一个字符可以保持无与伦比,未被替换.

现在假设我们要删除索引1,5 …上的字符,并将括号中的索引为0,4 …的字符放在.

String s = "1a2b3c4d5";
System.out.println(s.replaceAll("(.).","($1)"));
// prints "(1)(2)(3)(4)5"

A-HA!现在,您遇到与奇数输入完全相同的问题!你的最后一个字符与你的正则表达式不匹配,因为你的正则表达式需要两个字符,但最后只有一个字符是奇数长度的输入!

解决方案,再次是使匹配的第二个char可选:

String s = "1a2b3c4d5";
System.out.println(s.replaceAll("(.).?","($1)"));
// prints "(1)(2)(3)(4)(5)"

相关文章

最近看了一下学习资料,感觉进制转换其实还是挺有意思的,尤...
/*HashSet 基本操作 * --set:元素是无序的,存入和取出顺序不...
/*list 基本操作 * * List a=new List(); * 增 * a.add(inde...
/* * 内部类 * */ 1 class OutClass{ 2 //定义外部类的成员变...
集合的操作Iterator、Collection、Set和HashSet关系Iterator...
接口中常量的修饰关键字:public,static,final(常量)函数...