我有这个家庭作业问题,我需要使用正则表达式来删除字符串中的每个其他字符.
一方面,我必须删除索引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)"