Question

Java dispose-t-il d'un moyen intégré pour échapper au texte arbitraire afin qu'il puisse être inclus dans une expression régulière ?Par exemple, si mes utilisateurs saisissent « 5 $ », j'aimerais que cela corresponde exactement plutôt qu'un « 5 » après la fin de la saisie.

Était-ce utile?

La solution

Depuis Java 1.5, oui:

Pattern.quote("$5");

Autres conseils

Différence entre Pattern.quote et Matcher.quoteReplacement ce n'était pas clair pour moi avant de voir l'exemple suivant

s.replaceFirst(Pattern.quote("text to replace"), 
               Matcher.quoteReplacement("replacement text"));

Il est 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);

Je pense que ce que tu cherches c'est \Q$5\E.Regarde aussi Pattern.quote(s) introduit dans Java5.

Voir Modèle javadoc pour plus de détails.

Tout d'abord, si

  • vous utilisez replaceAll()
  • vous N'utilisez PAS Matcher.quoteReplacement()
  • le texte à remplacer comprend un 1 $

ça ne mettra pas un 1 à la fin.Il examinera l'expression régulière de recherche pour le premier groupe correspondant et sous-ajoutera CELA.C'est ce que signifie 1 $, 2 $ ou 3 $ dans le texte de remplacement :groupes correspondants à partir 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 de courrier électronique à partir de ceux-ci.En effet, cela semble être la manière par défaut de faire i18n dans Spring Framework.Je mets des balises XML, comme 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é, avec ce qui suit apparaissant dans un 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 sa saisie et replaceAll() a cherché dans l'expression régulière de recherche le troisième groupe correspondant, n'en a pas trouvé 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 saisir n'importe quel type de caractères, y compris les signes dollar, sans problème.Il s'est comporté exactement comme on pouvait s'y attendre.

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 insérer dans ce modèle protégé vos symboles spéciaux pour que ce modèle fonctionne non pas comme un stupide texte cité, 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 avec les caractères "\Q" et "\E", et s'il échappe à "\Q" et "\E".Cependant, si vous avez besoin d'effectuer un véritable échappement d'expression régulière (ou un échappement personnalisé), vous pouvez utiliser ce code :

String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));

Cette méthode renvoie : Certains/\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 correspondre à quelque chose qui ne fait pas partie du groupe de caractères.

C'est le lien vers Expressions régulières

Voici les informations d'image sur la négation :

Info about negation

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top