Java 如何仅显示包含多个连续字符的字符串中的某些字符?
假设我有一个字符串:Java 如何仅显示包含多个连续字符的字符串中的某些字符?,java,regex,Java,Regex,假设我有一个字符串:fffoooobbaarrr。 给定一个数字N,对于每个重复的字符,我想显示其中的N个 如果N=2,则输出为ffoobbaarr 如果N=3,则输出为fffooobbaarr 如果N=1,则输出为fobar 如果N=0,则输出为(空) 在学习regex时,经过一些实验,我发现这适用于N=2: Pattern pattern = Pattern.compile("(\\w)\\1{2,}"); System.out.println(pattern.matcher(input.r
fffoooobbaarrr
。
给定一个数字N,对于每个重复的字符,我想显示其中的N个
如果N=2,则输出为ffoobbaarr
如果N=3,则输出为fffooobbaarr
如果N=1,则输出为fobar
如果N=0,则输出为
(空)
在学习regex时,经过一些实验,我发现这适用于N=2:
Pattern pattern = Pattern.compile("(\\w)\\1{2,}");
System.out.println(pattern.matcher(input.replaceAll("$1$1"));
当然,在N=3、4等情况下不起作用。
如何修复此问题?您可以使用此正则表达式替换:
int n = 3 // or whatever number;
String repl = "";
if (n > 0) {
repl = str.replaceAll("((\\S)\\2{" + (n-1) + "})\\2*", "$1");
}
示例:(对于N=3)
示例:(对于N=2)
说明:
:启动捕获组#1(
:匹配1+非空白字符并捕获为组#2(\S)
:匹配相同字符的2个实例\2{2}
:结束捕获组#1)
:在捕获组外匹配相同字符的0+个实例\2*
使用下面的正则表达式作为观察者:
(\\w)(\\1{N})\\1*
细分:
匹配并捕获一个字母到捕获组1(\w)
匹配先前捕获的字母(\1{N})
次(捕获组2)N
匹配以下任意数量的重复\1*
0
结果为空输出),用于替换:
$2
Java代码():
您可以按如下方式创建图案和匹配器:
String text = "fffooooobbbbaarrr";
Pattern pattern = Pattern.compile("(.)\\1*");
Matcher matcher = pattern.matcher(text);
String result = "";
int len = 3;
while (matcher.find()) {
if(matcher.group().length() >= len) {
result += matcher.group().substring(0, len);
}else {
result += matcher.group();
}
}
System.out.println(result);
结果:
3 --> fffooobbbaarrr
2 --> ffoobbaarr
1 --> fobar
0 --> empty
这个想法是:
- 匹配任何重复字符
零次或多次()\1*
- 然后检查匹配的长度是否与您的长度相等,如果是,请使用子字符串获得您想要的长度
- 否则,请按原样使用匹配的字符
0时失败
@WiktorStribiżew OP是清晰的,如果N=0,输出是(空的)@WiktorStribiżew我认为应该是更多文本,这里是ffoobbaarr。
@WiktorStribiżew如果N=0
,那么输出当然是空字符串。如果N=2
,@YCF\L做对了:)我想你在使用\1
替换时投了反对票,请使用$1
。此外,请注意,n
可能应该是n-1
,\\2+
应该是\\2*
。是的,我认为如果n=0,使用简单的if
检查返回空字符串更容易。虽然我开始怀疑我是否理解操作逻辑。现在检查:它应该是System.out.println(repl)代码>而不是System.out.println(str)
Oh np,谢谢你准备了一个代码演示(现在是答案的一部分)谢谢@anubhava。男人的正则表达式很复杂
3 --> fffooobbbaarrr
2 --> ffoobbaarr
1 --> fobar
0 --> empty