regex如何使用(正则表达式)删除java中的重复字母,并且不区分大小写
我一直在尝试用字母的小写版本(java)替换任何重复的字母。例如:
我想要一个映射以下内容的函数:
bob -> bob
bOb -> bob
bOOb -> bob
bOob -> bob
boOb -> bob
bob -> bob
Bob -> Bob
bOb -> bob
但是,我使用regexs(在Java中)并没有成功地做到这一点
我尝试了以下方法:
String regex = "([A-za-z])\\1+";
String str ="bOob";
Pattern pattern = Pattern.compile(regex , Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
System.out.println(matcher.replaceAll("$1"));
但是,这将返回bOb而不是bOb。(对胸部有效)
我还尝试:
Pattern pattern = Pattern.compile("(?i)([A-Za-z0-9])(?=\\1)", Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);
return matcher.replaceAll("");
这解决了一个问题,现在bOob->;但是bob带来了另一个问题,因为现在它将胸部映射到bob
注意:它还应映射boooooooooooob->;波波波波
我觉得在这一点上,循环字符串并基于每个字符执行一些逻辑可能更容易,但我不想放弃使用regexs。。。如果存在使用regexs的解决方案,那么它是否比遍历每个字符的循环更有效
提前谢谢
PS:我知道在传递字符串之前,可以将所有内容的大小写都降低,但这不是我想要的,因为它映射:
鲍勃->;鲍勃
# 1 楼答案
我想这就是我一直在寻找的代码(基于公认的答案):
它所做的是替换任何重复的字母(无论是否大写),并将其替换为单个非大写字母
我认为它非常接近我想要的工作方式,尽管它映射了Bbob->;上下快速移动我怀疑,因为它没有映射到Bob,它会对我使用它的原因产生太大的影响
顺便说一句,如果有人能看到如何优化这个,请随意评论!这确实让我有点恼火。reset(),但我不确定是否有必要
# 2 楼答案
在这里使用Matcher#group()而不是
$1
允许您使用
toLowerCase()
然后编辑(回应OP的评论)
Matcher#group(n)
与$n
相同。它指的是第n个捕获组。所以,group(1)
和$1
都是捕获O
,除了可以切换捕获toLowerCase()
循环由}来初始化组,以便
replaceAll()
运行,而不是由find()
运行^需要{group(1)
在调用replaceAll()
之前返回捕获但是,这也意味着捕获保持不变,这满足了您的要求,但需要为类似于boobboobboobbooboooob的字符串重置匹配器(注意双b)。循环必须由
Mathcer#find()
现在驱动,这意味着replaceAll()
与replaceFirst()
进行交易这里使用Matcher#start()来确定匹配是否在输入的开头,而大小写保持不变