web-dev-qa-db-fra.com

Méthode replaceAll () et caractères d'échappement

La ligne

System.out.println("\\");

affiche une seule barre oblique inverse (\). Et

System.out.println("\\\\");

imprime les doubles barres obliques (\\). Compris!

Mais pourquoi dans le code suivant:

class ReplaceTest
{
    public static void main(String[] args)
    {
        String s = "hello.world";
        s = s.replaceAll("\\.", "\\\\");
        System.out.println(s);
    }
}

est la sortie:

hello\world

au lieu de

hello\\world

Après tout, la méthode replaceAll() remplace un point (\\.) par (\\\\).

Quelqu'un peut-il s'il vous plaît expliquer cela?

21
WickeD

Lorsque vous remplacez des caractères à l'aide d'expressions régulières, vous êtes autorisé à utiliser des références arrières, telles que \1 pour remplacer l'utilisation d'un groupe dans la correspondance.

Cela signifie toutefois que la barre oblique inverse est un caractère spécial. Par conséquent, si vous souhaitez réellement utiliser une barre oblique inversée, vous devez l'échapper.

Ce qui signifie qu’il doit être réellement échappé deux fois lorsqu’il est utilisé dans une chaîne Java. (D'abord pour l'analyseur de chaîne, puis pour l'analyseur de regex.)

23
Reverend Gonzo

Le javadoc de replaceAll dit:

Notez que les barres obliques inverses (\) et les signes dollar ($) dans le remplacement chaîne peut entraîner des résultats différents de ceux obtenus s'il s'agissait de traité comme une chaîne de remplacement littéral; voir Matcher.replaceAll. Utilisation Matcher.quoteReplacement (Java.lang.String) pour supprimer le spécial signification de ces caractères, si vous le souhaitez.

14
JB Nizet

Si vous n'avez pas besoin de regex pour le remplacement et que vous devez simplement remplacer des chaînes exactes, échappez les caractères de contrôle de regex avant le remplacement.

String trickyString = "$Ha!I'm tricky|.|";
String safeToUseInReplaceAllString = Pattern.quote(trickyString);
4
Gorky

Ceci est un addenda formaté à mon commentaire 

s = s.replaceAll("\\.", Matcher.quoteReplacement("\\"));  

EST PLUS LISTE ET SIGNIFICATIF QUE 

s = s.replaceAll("\\.", "\\\\\\");
3
Christophe Blin

Je n'aime pas cette implémentation de regex. Nous devrions pouvoir échapper aux caractères avec un seul '\', pas '\'. Quoi qu'il en soit, si vous voulez obtenir THIS.Out_Of_That, vous pouvez le faire:

String prefix = role.replaceFirst("(\\.).*", "");

Donc, vous obtenez le préfixe = CECI;

0
cepix

Je crois que dans ce cas particulier, il serait plus facile d'utiliser remplacer plutôt que de remplacer tout .. Le révérend Gonzo a la bonne réponse lorsqu'il parle de fuir le personnage.

Utiliser replaceAll:

s = s.replaceAll("\\.", "\\\\\\\\");

En utilisant remplacer:

s = s.replaceAll(".", "\\");

remplacer prend simplement une chaîne à associer, pas une expression régulière. 

0
Bogoth

La barre oblique inverse est un caractère d'échappement dans Java Strings. par exemple. La barre oblique inverse a une signification prédéfinie en Java. Vous devez utiliser "\ \" pour définir une seule barre oblique inverse. Si vous voulez définir "\ w", vous devez utiliser "\\w" dans votre expression rationnelle. Si vous voulez utiliser une barre oblique inversée en tant que littéral, vous devez taper \\\\, car\est également un caractère d'échappement dans les expressions régulières. 

0
David Mathias