J'essaye de convertir le String
\something\
en String
\\something\\
utilisation replaceAll
, mais j'obtiens toujours toutes sortes d'erreurs. Je pensais que c'était la solution:
theString.replaceAll("\\", "\\\\");
Mais cela donne l'exception ci-dessous:
java.util.regex.PatternSyntaxException: Unexpected internal error near index 1
la source
String#replaceAll()
quand même l' utiliser , vous pouvez citer la chaîne de remplacement avec Matcher # quoteReplacement () :theString.replaceAll("\\", Matcher.quoteReplacement("\\\\"));
Pour éviter ce genre de problème, vous pouvez utiliser
replace
(qui prend une chaîne simple) au lieu dereplaceAll
(qui prend une expression régulière). Vous devrez toujours échapper les contre-obliques, mais pas de la manière sauvage requise avec les expressions régulières.la source
TLDR: utilisez
theString = theString.replace("\\", "\\\\");
plutôt.Problème
replaceAll(target, replacement)
utilise la syntaxe d'expression régulière (regex) pourtarget
et partiellement pourreplacement
.Le problème est qu'il
\
s'agit d'un caractère spécial dans l'expression régulière (il peut être utilisé comme\d
pour représenter un chiffre) et dans une chaîne littérale (il peut être utilisé comme"\n"
pour représenter un séparateur de ligne ou\"
pour échapper un double guillemet qui normalement représenterait la fin de la chaîne littérale).Dans ces deux cas, pour créer un
\
symbole, nous pouvons l' échapper (le rendre littéral au lieu d'un caractère spécial) en le plaçant\
devant lui (comme nous nous échappons"
dans une chaîne littérale via\"
).Donc, pour
target
regex représentant un\
symbole, il faudra tenir\\
, et une chaîne littérale représentant un tel texte devra ressembler à"\\\\"
.Nous nous sommes donc échappés
\
deux fois:\\
"\\\\"
(chacun\
est représenté par"\\"
).En cas de
replacement
\
c'est aussi spécial là-bas. Cela nous permet d'échapper à un autre caractère spécial$
qui, via la$x
notation, nous permet d'utiliser une partie des données appariées par regex et détenues par le groupe de capture indexé commex
, comme"012".replaceAll("(\\d)", "$1$1")
correspondra chaque chiffre, placez-le dans le groupe de capture 1 et$1$1
le remplacera par ses deux copies (il le dupliquera) résultant en"001122"
.Encore une fois, pour laisser
replacement
représenter\
littéral, nous devons lui échapper avec un supplément,\
ce qui signifie que:\\
\\
ressemble à"\\\\"
MAIS puisque nous voulons
replacement
contenir deux contre-obliques, nous aurons besoin"\\\\\\\\"
(chacun\
représenté par un"\\\\"
).Donc la version avec
replaceAll
peut ressembler àUn moyen plus simple
Pour vous faciliter la vie, Java fournit des outils permettant d'échapper automatiquement le texte dans
target
et dans desreplacement
parties. Alors maintenant, nous pouvons nous concentrer uniquement sur les chaînes et oublier la syntaxe regex:qui dans notre cas peut ressembler à
Encore mieux
Si nous n'avons pas vraiment besoin du support de la syntaxe regex, n'impliquons pas
replaceAll
du tout. Au lieu de cela, utilisonsreplace
. Les deux méthodes remplaceront tous lestarget
s, maisreplace
n'impliquent pas de syntaxe regex. Pour que tu puisses simplement écrirela source
Vous devrez échapper la barre oblique inverse (échappée) dans le premier argument car il s'agit d'une expression régulière. Replacement (2nd argument - see Matcher # replaceAll (String) ) a également sa signification particulière pour les barres obliques inverses, vous devrez donc les remplacer par:
la source
Oui ... au moment où le compilateur regex voit le modèle que vous lui avez donné, il ne voit qu'un seul backslash (puisque le lexer de Java a transformé le double backwhack en un seul). Vous devez remplacer
"\\\\"
par"\\\\"
, croyez-le ou non! Java a vraiment besoin d'une bonne syntaxe de chaîne brute.la source