Réponses:
Depuis Java 1.5, oui :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
il reviendra MicE
. Vous attendez would't pour revenir MICE
parce que vous n'avez pas appliqué toUpperCase()
sur ic
. Dans mon exemple, il quote()
est également appliqué sur l' .*
insert replaceAll()
. Vous devez faire autre chose, peut .replaceAll("*","\\E.*\\Q")
- être que cela fonctionnerait, mais c'est contre-intuitif.
*.wav
en motif regex \*\.wav
et le replaceAll le transformerait \.*\.wav
, ce qui signifie qu'il le ferait correspond à des fichiers dont le nom consiste en un nombre arbitraire de périodes suivies de .wav
. Vous en auriez probablement eu besoin replaceAll("\\*", ".*")
s'ils étaient partis avec l'implémentation la plus fragile qui repose sur la reconnaissance de tous les characheurs de regex actifs possibles et leur échappance individuelle ... serait-ce tellement plus facile?
La différence entre Pattern.quote
et Matcher.quoteReplacement
n'était pas claire pour moi avant de voir l'exemple suivant
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
remplace les caractères spéciaux dans les chaînes de recherche d'expression régulière, comme. | + () Etc., et Matcher.quoteReplacement
remplace les caractères spéciaux dans les chaînes de remplacement, comme \ 1 pour les références arrières.
quoteReplacement
ne se soucie que des deux symboles $
et \
qui peuvent par exemple être utilisés dans des chaînes de remplacement comme références arrières $1
ou \1
. Il ne doit donc pas être utilisé pour échapper / citer une expression régulière.
$Group$
avec T$UYO$HI
. Le $
symbole est spécial à la fois dans le motif et dans le remplacement:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Il peut être trop tard pour répondre, mais vous pouvez également utiliser Pattern.LITERAL
, qui ignorerait tous les caractères spéciaux lors du formatage:
Pattern.compile(textToFormat, Pattern.LITERAL);
Pattern.CASE_INSENSITIVE
Je pense que c'est ce que vous recherchez \Q$5\E
. Voir également Pattern.quote(s)
introduit dans Java5.
Voir Pattern javadoc pour plus de détails.
Tout d'abord, si
il ne mettra pas un 1 à la fin. Il examinera l'expression rationnelle de recherche pour le premier groupe et le sous-groupe correspondants. C'est ce que signifie $ 1, $ 2 ou $ 3 dans le texte de remplacement: les groupes correspondants du modèle de recherche.
Je branche fréquemment de longues chaînes de texte dans des fichiers .properties, puis je génère des sujets et des corps d'e-mails à partir de ceux-ci. En effet, cela semble être la façon par défaut de faire i18n dans Spring Framework. J'ai mis des balises XML, en tant qu'espaces réservés, dans les chaînes et j'utilise replaceAll () pour remplacer les balises XML par les valeurs au moment de l'exécution.
J'ai rencontré un problème où un utilisateur saisissait un chiffre en dollars et en cents, avec un signe dollar. replaceAll () s'est étouffé dessus, les éléments suivants apparaissant dans une stracktrace:
java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)
Dans ce cas, l'utilisateur avait entré "$ 3" quelque part dans son entrée et replaceAll () est allé chercher dans l'expression régulière de recherche pour le troisième groupe correspondant, n'en a pas trouvé un et a vomi.
Donné:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
remplacer
msg = msg.replaceAll("<userInput \\/>", userInput);
avec
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
résolu le problème. L'utilisateur peut entrer n'importe quel type de caractères, y compris les signes dollar, sans problème. Il s'est comporté exactement comme vous vous y attendez.
Pour avoir un motif protégé, vous pouvez remplacer tous les symboles par "\\\\", à l'exception des chiffres et des lettres. Et après cela, vous pouvez mettre dans ce motif protégé vos symboles spéciaux pour que ce motif ne fonctionne pas comme un texte cité stupide, mais vraiment comme un motif, mais le vôtre. Sans symboles spéciaux utilisateur.
public class Test {
public static void main(String[] args) {
String str = "y z (111)";
String p1 = "x x (111)";
String p2 = ".* .* \\(111\\)";
p1 = escapeRE(p1);
p1 = p1.replace("x", ".*");
System.out.println( p1 + "-->" + str.matches(p1) );
//.*\ .*\ \(111\)-->true
System.out.println( p2 + "-->" + str.matches(p2) );
//.* .* \(111\)-->true
}
public static String escapeRE(String str) {
//Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
//return escaper.matcher(str).replaceAll("\\\\$1");
return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
}
}
Pattern.quote ("blabla") fonctionne bien.
Le Pattern.quote () fonctionne bien. Il entoure la phrase des caractères " \ Q " et " \ E ", et s'il s'échappe "\ Q" et "\ E". Cependant, si vous devez faire un véritable échappement d'expression régulière (ou échappement personnalisé), vous pouvez utiliser ce code:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Cette méthode renvoie: Some / \ s / wText * / \, **
Code par exemple et tests:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Le symbole ^ (négation) est utilisé pour faire correspondre quelque chose qui n'est pas dans le groupe de caractères.
Ceci est le lien vers les expressions régulières
Voici les informations d'image sur la négation:
\Q
et\E
. Cela peut conduire à des résultats inattendus, par exemplePattern.quote("*.wav").replaceAll("*",".*")
entraînera\Q.*.wav\E
et non.*\.wav
, comme vous pouvez vous y attendre.