wake-up-neo.com

So ersetzen Sie Groß- und Kleinschreibung in Teilzeichenfolgen in Java

Wie kann ich mit der Methode replace(CharSequence target, CharSequence replacement) in String die Groß- und Kleinschreibung unabhängig machen?

Zum Beispiel, wie es jetzt funktioniert:

String target = "FooBar";
target.replace("Foo", "") // would return "Bar"

String target = "fooBar";
target.replace("Foo", "") // would return "fooBar"

Wie kann ich es so ersetzen lassen (oder wenn es eine geeignetere Methode gibt), ohne Berücksichtigung der Groß- und Kleinschreibung, sodass beide Beispiele "Balken" zurückgeben?

98
JPL
String target = "FOOBar";
target = target.replaceAll("(?i)foo", "");
System.out.println(target);

Ausgabe:

Bar

Es ist erwähnenswert, dass replaceAll das erste Argument als Regex-Muster behandelt, was unerwartete Ergebnisse verursachen kann. Um dies zu lösen, verwenden Sie auch Pattern.quote , wie in den Kommentaren vorgeschlagen.

230
smas

Vielleicht nicht so elegant wie andere Ansätze, aber es ist ziemlich solide und leicht zu folgen, besonders. für Menschen, die nicht mit Java vertraut sind. Was mich an der String-Klasse interessiert, ist folgende: Es gibt eine sehr lange Zeit, und obwohl sie eine globale Ersetzung mit regexp und eine globale Ersetzung mit Strings (über CharSequences) unterstützt, hat dieser letzte keinen einfachen booleschen Parameter : 'isCaseInsensitive'. Eigentlich hätten Sie gedacht, dass allein durch das Hinzufügen dieses kleinen Schalters all die Mühe, die seine Abwesenheit für Anfänger verursacht, hätte vermieden werden können. Auf JDK 7 unterstützt String noch diese kleine Ergänzung nicht! 

Nun, ich werde aufhören zu greifen. Für alle, die sich mit Java noch nicht auskennen, ist hier das Ausschneiden/Einfügen deus ex machina . Wie gesagt, nicht so elegant und gewinne keinen schlanken Codierpreis, aber es funktioniert und ist zuverlässig. Alle Kommentare können Sie gerne beitragen. (Ja, ich weiß, StringBuffer ist wahrscheinlich die bessere Wahl für die Verwaltung der zwei Zeichenfolgen-Mutationslinien, aber es ist leicht genug, die Techniken auszutauschen.)

public String replaceAll(String findtxt, String replacetxt, String str, 
        boolean isCaseInsensitive) {
    if (str == null) {
        return null;
    }
    if (findtxt == null || findtxt.length() == 0) {
        return str;
    }
    if (findtxt.length() > str.length()) {
        return str;
    }
    int counter = 0;
    String thesubstr = "";
    while ((counter < str.length()) 
            && (str.substring(counter).length() >= findtxt.length())) {
        thesubstr = str.substring(counter, counter + findtxt.length());
        if (isCaseInsensitive) {
            if (thesubstr.equalsIgnoreCase(findtxt)) {
                str = str.substring(0, counter) + replacetxt 
                    + str.substring(counter + findtxt.length());
                // Failing to increment counter by replacetxt.length() leaves you open
                // to an infinite-replacement loop scenario: Go to replace "a" with "aa" but
                // increment counter by only 1 and you'll be replacing 'a's forever.
                counter += replacetxt.length();
            } else {
                counter++; // No match so move on to the next character from
                           // which to check for a findtxt string match.
            }
        } else {
            if (thesubstr.equals(findtxt)) {
                str = str.substring(0, counter) + replacetxt 
                    + str.substring(counter + findtxt.length());
                counter += replacetxt.length();
            } else {
                counter++;
            }
        }
    }
    return str;
}
11
Matt Campbell

Wenn Sie sich nicht um den Fall kümmern, ist es Ihnen vielleicht egal, ob er alle Fälle zurückgibt:

target.toUpperCase().replace("FOO", "");

Reguläre Ausdrücke sind aufgrund der Tatsache, dass einige Zeichen reserviert sind, recht komplex zu verwalten. Beispielsweise erzeugt "foo.bar".replaceAll(".") eine leere Zeichenfolge, da der Punkt "alles" bedeutet. Wenn Sie nur den Punkt ersetzen möchten, sollte der Punkt als Parameter "\\." angegeben werden.

Eine einfachere Lösung ist die Verwendung von StringBuilder-Objekten zum Suchen und Ersetzen von Text. Es braucht zwei: einen, der den Text in Kleinbuchstaben enthält, während der zweite die ursprüngliche Version enthält. Die Suche wird nach Kleinbuchstaben durchgeführt und der erkannte Index ersetzt auch den Originaltext.

public class LowerCaseReplace 
{
    public static String replace(String source, String target, String replacement)
    {
        StringBuilder sbSource = new StringBuilder(source);
        StringBuilder sbSourceLower = new StringBuilder(source.toLowerCase());
        String searchString = target.toLowerCase();

        int idx = 0;
        while((idx = sbSourceLower.indexOf(searchString, idx)) != -1) {
            sbSource.replace(idx, idx + searchString.length(), replacement);
            sbSourceLower.replace(idx, idx + searchString.length(), replacement);
            idx+= replacement.length();
        }
        sbSourceLower.setLength(0);
        sbSourceLower.trimToSize();
        sbSourceLower = null;

        return sbSource.toString();
    }


    public static void main(String[] args)
    {
        System.out.println(replace("xXXxyyyXxxuuuuoooo", "xx", "**"));
        System.out.println(replace("FOoBaR", "bar", "*"));
    }
}
7
ilmassa

Für Nicht-Unicode-Zeichen:

String result = Pattern.compile("(?i)препарат", 
Pattern.UNICODE_CASE).matcher(source).replaceAll("БАД");
3
MisterParser

Ich mag smas 's answer das replaceAll mit einem regulären Ausdruck verwendet. Wenn Sie den gleichen Austausch mehrmals durchführen, ist es sinnvoll, den regulären Ausdruck einmal vorab zu kompilieren:

import Java.util.regex.Pattern;

public class Test { 

    private static final Pattern fooPattern = Pattern.compile("(?i)foo");

    private static removeFoo(s){
        if (s != null) s = fooPattern.matcher(s).replaceAll("");
        return s;
    }

    public static void main(String[] args) {
        System.out.println(removeFoo("FOOBar"));
    }
}
3

org.Apache.commons.lang3.StringUtils:

public static String replaceIgnoreCase (String-Text String searchString... String ersetzen

Groß- und Kleinschreibung ersetzt alle Vorkommen eines Strings innerhalb eines anderen Strings.

1
Michael

Machen Sie es einfach ohne Bibliotheken von Drittanbietern:

    final String source = "FooBar";
    final String target = "Foo";
    final String replacement = "";
    final String result = Pattern.compile(target, Pattern.LITERAL | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(source)
.replaceAll(Matcher.quoteReplacement(replacement));
0
gouessej