142 votes

Comment remplacer la casse littérale de sous-chaînes dans Java

À l'aide de la méthode de replace(CharSequence target, CharSequence replacement) Chaîne, comment puis-je faire la cible de la casse?

Par exemple, la façon dont il fonctionne à l'heure actuelle:

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

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

Comment puis-je faire remplacer (ou si il y a une méthode plus appropriée) est insensible à la casse, de sorte que les deux exemples de retour "Bar"?

Merci.

324voto

smas Points 8299
    String target = "FOOBar";
    target = target.replaceAll("(?i)foo", "");
    System.out.println(target);

sortie: Bar

10voto

ilmassa Points 21

Les expressions régulières sont assez complexes à gérer en raison du fait que certains caractères sont réservés: par exemple, "foo.bar".replaceAll(".") produit une chaîne vide, parce que la dot signifie "n'importe quoi" Si vous souhaitez remplacer uniquement le point doit être indiqué comme paramètre "\\.".

Une solution plus simple est d'utiliser StringBuilder objets pour rechercher et remplacer du texte. Il faut être deux: un qui contient le texte dans la version en minuscules tandis que la seconde contient la version originale. La recherche est effectuée sur les minuscules matières et de l'index détectées seront également remplacer le texte original.

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", "*"));
    }
}

10voto

Si vous ne se soucient pas le cas, alors vous peut-être qu'il n'a pas d'importance si elle retourne tous les upcase:

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

9voto

Matt Campbell Points 446

Pas élégant, peut-être que d'autres approches, mais il est assez solide et facile à suivre, esp. pour les personnes plus récente de Java. Une chose qui me met sur la classe String est ceci: Il a été autour pendant un temps très long et, tandis qu'il prend en charge un remplacement global avec les regexp et un remplacement global avec des Chaînes de caractères (via CharSequences), cette dernière ne dispose pas d'un simple paramètre booléen: 'isCaseInsensitive'. Vraiment, vous auriez ai pensé que, tout en ajoutant qu'un petit interrupteur, toutes les difficultés que son absence entraîne pour les débutants en particulier, auraient pu être évités. Maintenant sur le JDK 7, Chaîne encore ne prend pas en charge ce petit plus!

Enfin, bref, je vais arrêter de ronchonner. Pour tout le monde, en particulier la plus récente de Java, voici votre "couper et coller" deus ex machina. Comme je l'ai dit, pas élégant, et pas de victoire vous toute nappe de codage des prix, mais il fonctionne et qui est fiable. Tout commentaire, n'hésitez pas à contribuer. (Oui, je sais, StringBuffer est probablement un meilleur choix de gérer les deux chaîne de caractères mutation lignes, mais il est assez facile de permuter les techniques.)

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;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X