簡體   English   中英

如何使用(正則表達式)刪除java中重復的字母並且不區分大小寫

[英]How to remove repeated letters in java using (Regular Expressions) and being case Insensitive

我一直試圖做的是用他們的小寫字母(在java中)替換任何重復的字母。 例如:

我想要一個映射的函數:

bob -> bob
bOb -> bob
bOOb -> bob
bOob -> bob
boOb -> bob
bob -> bob
Bob -> Bob
bOb -> bob

但是,我沒有成功使用正則表達式(在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。 (它適用於boOb)。

我也嘗試過:

        Pattern pattern = Pattern.compile("(?i)([A-Za-z0-9])(?=\\1)", Pattern.CASE_INSENSITIVE);
        Matcher matcher = pattern.matcher(str);
        return matcher.replaceAll("");

這解決了一個問題,現在bOob - > bob但是帶來了另一個問題,因為現在它將boOb映射到bob。

注意:它還應該映射BOobOoboObOoObooOoOoOoOoOOb - > Bobobobobob。

我覺得在這一點上循環字符串並根據每個字符做一些邏輯可能更容易但我只是不想放棄使用正則表達式...如果存在使用正則表達式的解決方案,是否更多可能比循環遍歷每個角色更有效?

提前致謝!

PS:我知道在傳遞字符串之前可以簡單地降低案例,但這不是我想要的,因為它映射:

鮑勃 - >鮑勃

在這里使用Matcher#group()而不是$1

if (matcher.find()) {
    System.out.println(matcher.replaceAll(matcher.group(1)
                                          .toLowerCase()));
}

讓您使用toLowerCase()然后。

編輯 :(回應OP的評論)

Matcher#group(n)$n相同 - 它指的是第n個捕獲組。 因此, group(1)$1都捕獲O除了您可以將捕獲切換到toLowerCase()

循環由replaceAll()運行,而不是由find() Matcher#find()是初始化組所必需的,因此group(1)在調用replaceAll()之前返回捕獲。

但是,這也意味着捕獲保持不變,滿足您的要求,但需要重置匹配器,如BOobbOobboObbOoObbooOoOoOoOoOOb (注意雙b)。 循環必須由Mathcer#find()驅動,這意味着replaceAll()replaceFirst()進行交易。

String regex = "([A-Za-z])\\1+";
String str = "BOobbOobboObbOoObbooOoOoOoOoOObb";

Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(str);

while (matcher.find()) {
    str = matcher.replaceFirst(matcher.start() > 0 ? matcher.group(1)
                                    .toLowerCase() : matcher.group(1));
    matcher.reset(str);
}

System.out.println(str); // Bobobobobob

此處使用匹配器#start()來識別匹配是否在輸入的開始處,其中保持不變的情況。

我認為這是我正在尋找的代碼(根據接受的答案):

public String removeRepeatedLetters(String str, boolean caseSensitive){
    if(caseSensitive){
        return this.removeRepeatedLetters(str); //uses case sensitive version
    }else{
        Pattern patternRep = Pattern.compile("([A-Za-z])(\\1+)", Pattern.CASE_INSENSITIVE);
        Matcher matcher = patternRep.matcher(str);
        String output = str;
        while(matcher.find()){
            String matchStr = matcher.group(1);
            output = matcher.replaceFirst(matchStr.toLowerCase());
            matcher = patternRep.matcher(output);
            matcher.reset();
        }
        return output;
    }   
}

它的作用是替換任何重復的字母(無論是大寫字母還是大寫字母),並用一個非大寫字母替換它們。

我認為非常接近我想要的工作,雖然它映射了Bbob - > bob。 我懷疑,因為它沒有映射到Bob,它會影響我使用它的原因太多了。

順便說一句,如果有人能看到如何優化這個,請隨時評論! 它確實讓我煩惱了.reset(),雖然我不確定它是否是必要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM