Domanda

Java dispone di un modo integrato per sfuggire al testo arbitrario in modo che possa essere incluso in un'espressione regolare?Ad esempio, se i miei utenti inseriscono "$5", vorrei corrispondere esattamente a questo anziché a "5" dopo la fine dell'input.

È stato utile?

Soluzione

Da Java 1.5, sì:

Pattern.quote("$5");

Altri suggerimenti

Differenza fra Pattern.quote E Matcher.quoteReplacement non mi era chiaro prima di vedere il seguente esempio

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

Potrebbe essere troppo tardi per rispondere, ma puoi anche usarlo Pattern.LITERAL, che ignorerebbe tutti i caratteri speciali durante la formattazione:

Pattern.compile(textToFormat, Pattern.LITERAL);

Penso che quello che stai cercando sia \Q$5\E.Vedi anche Pattern.quote(s) introdotto in Java5.

Vedere Modello javadoc per i dettagli.

Prima di tutto, se

  • usi replaceAll()
  • NON usi Matcher.quoteReplacement()
  • il testo da sostituire include $ 1

non metterà un 1 alla fine.Esaminerà l'espressione regolare di ricerca per il primo gruppo corrispondente e inserirà QUELLA.Questo è il significato di $1, $2 o $3 nel testo sostitutivo:gruppi corrispondenti dal modello di ricerca.

Inserisco spesso lunghe stringhe di testo nei file .properties, quindi genero gli oggetti e i corpi delle email da questi.In effetti, questo sembra essere il modo predefinito per eseguire i18n in Spring Framework.Inserisco i tag XML, come segnaposto, nelle stringhe e utilizzo replaceAll() per sostituire i tag XML con i valori in fase di runtime.

Mi sono imbattuto in un problema in cui un utente immetteva una cifra in dollari e centesimi, con il simbolo del dollaro.replaceAll() si è bloccato, con quanto segue visualizzato in uno 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)

In questo caso, l'utente aveva inserito "$3" da qualche parte nel proprio input e replaceAll() è andato a cercare nella regex di ricerca il terzo gruppo corrispondente, non ne ha trovato uno e ha vomitato.

Dato:

// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input

sostituendo

msg = msg.replaceAll("<userInput \\/>", userInput);

con

msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));

problema risolto.L'utente può inserire qualsiasi tipo di carattere, compresi i simboli del dollaro, senza problemi.Si è comportato esattamente come ti aspetteresti.

Per avere un pattern protetto è possibile sostituire tutti i simboli con "\\\\", eccetto cifre e lettere.E dopo puoi inserire in quel modello protetto i tuoi simboli speciali per far sì che questo modello funzioni non come uno stupido testo tra virgolette, ma in realtà come uno schema, ma il tuo.Senza simboli speciali utente.

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") funziona bene.

Il Pattern.quote() funziona bene.Racchiude la frase con i caratteri "\Q" E "\E", e se sfugge a "\Q" e "\E".Tuttavia, se è necessario eseguire l'escape di un'espressione regolare reale (o un escape personalizzato), è possibile utilizzare questo codice:

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

Questo metodo restituisce: Alcuni/\s/wText*/\,**

Codice ad esempio e test:

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

Il simbolo ^(Negazione) viene utilizzato per corrispondere a qualcosa che non è nel gruppo di caratteri.

Questo è il collegamento a Espressioni regolari

Ecco le informazioni sull'immagine sulla negazione:

Info about negation

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top