it-swarm.com.de

Liste aller Sonderzeichen, die in einer Regex enthalten sein müssen

Ich versuche, eine Anwendung zu erstellen, die einer Nachrichtenvorlage mit einer Nachricht entspricht, die ein Benutzer zu senden versucht. Ich verwende Java-Regex zum Abgleichen der Nachricht. Die Vorlage/Nachricht kann Sonderzeichen enthalten.

Wie erhalte ich die vollständige Liste der Sonderzeichen, die geschützt werden müssen, damit meine Regex in den maximal möglichen Fällen funktioniert und übereinstimmt?

Gibt es eine universelle Lösung, um alle Sonderzeichen in Java-Regex zu umgehen?

83
Avinash Nair

Sie können sich den Javadoc der Pattern-Klasse ansehen: http://docs.Oracle.com/javase/8/docs/api/Java/util/regex/Pattern.html

Sie müssen jedes dort aufgelistete Zeichen entfernen, wenn Sie das reguläre Zeichen und nicht die spezielle Bedeutung wünschen.

Als vielleicht einfachere Lösung können Sie die Vorlage zwischen\Q und\E setzen - alles dazwischen gilt als entkommen.

75
Sorin
  • Java-Zeichen, die in regulären Ausdrücken maskiert werden müssen, sind:
    \.[]{}()<>*+-=!?^$|
  • Zwei der schließenden Klammern (] und }) müssen erst nach dem Öffnen der gleichen Art von Halterung entkommen werden.
  • Im []- Klammern einige Zeichen (wie + und -) arbeite manchmal ohne Flucht.
78
Tobi G.

Um zu entkommen, können Sie dies einfach aus Java 1.5 verwenden:

Pattern.quote("$test");

Sie werden genau mit dem Wort $test übereinstimmen.

20
madx

Laut der Dokumentationsseite String Literals/Metacharacters sind dies:

<([{\^-=$!|]})?*+.>

Es wäre auch cool, diese Liste irgendwo im Code referenzieren zu lassen, aber ich weiß nicht, wo das sein könnte ...

15
Bohdan

Auf @ Sorins Vorschlag der Java-Pattern-Dokumente sieht es so aus, als wären die Zeichen zu entkommen mindestens

\.[{(*+?^$|
5
pete

Zusammengefasst, was alle gesagt haben, schlage ich Folgendes vor, um die Liste der Charaktere, die speziell für RegExp bestimmt sind, in ihrem eigenen String eindeutig aufzuführen und um nicht zu versuchen, Tausende von "\\" visuell zu analysieren. Das scheint für mich ziemlich gut zu funktionieren:

final String regExSpecialChars = "<([{\\^-=$!|]})?*+.>";
final String regExSpecialCharsRE = regExSpecialChars.replaceAll( ".", "\\\\$0");
final Pattern reCharsREP = Pattern.compile( "[" + regExSpecialCharsRE + "]");

String quoteRegExSpecialChars( String s)
{
    Matcher m = reCharsREP.matcher( s);
    return m.replaceAll( "\\\\$0");
}
4
NeuroDuck

auf der anderen Seite der Münze sollten Sie Regex "non-char" verwenden, der folgendermaßen aussieht, wenn Sonderzeichen = allChars - number - ABC - Leerzeichen in Ihrem App - Kontext stehen.

String regepx = "[^\\s\\w]*";
2
Bo6Bear

Die Pattern.quote(String s) Art macht, was Sie wollen. Es lässt jedoch ein wenig zu wünschen übrig; es entgeht den einzelnen Zeichen eigentlich nicht, es umschließt die Zeichenkette nur mit \Q...\E.

Es gibt keine Methode, die genau das tut, wonach Sie suchen, aber die gute Nachricht ist, dass es eigentlich ziemlich einfach ist, alle Sonderzeichen in einem regulären Ausdruck Java zu maskieren:

regex.replaceAll("[\\W]", "\\\\$0")

Warum funktioniert das? Nun, in der Dokumentation zu PatternNAME _ heißt es ausdrücklich, dass es zulässig ist, nicht-alphabetische Zeichen zu maskieren, die nicht unbedingt maskiert werden müssen:

Es ist ein Fehler, einen Backslash vor einem Buchstaben zu verwenden, der kein Escape-Konstrukt kennzeichnet. Diese sind für zukünftige Erweiterungen der Sprache für reguläre Ausdrücke reserviert. Ein umgekehrter Schrägstrich kann vor einem nicht-alphabetischen Zeichen verwendet werden, unabhängig davon, ob dieses Zeichen Teil eines Konstrukts ohne Flucht ist.

Beispielsweise ist ; kein Sonderzeichen in einem regulären Ausdruck. Wenn Sie es jedoch umgehen, interpretiert Pattern\; weiterhin als ;. Hier noch ein paar Beispiele:

  • > wird \>, was > entspricht
  • [ wird \[, was die maskierte Form von [ ist
  • 8 ist noch 8.
  • \) wird \\\), was die maskierten Formen von \ und ( verkettet.

Hinweis: Der Schlüssel ist die Definition von "nicht alphabetisch", was in der Dokumentation wirklich "nicht - Wort" bedeutet "Zeichen oder Zeichen außerhalb des Zeichensatzes [a-zA-Z_0-9].

2
wheeler

Angenommen, Sie haben die Liste der Escape-Zeichen, die Java Regex verwendet, und vertrauen dieser Liste (um maßgeblich zu sein) wenn es tatsächlich notwendig ist:

private static final char[] escapeChars = { '<', '(', '[', '{', '\\', '^', '-', '=', '$', '!', '|', ']', '}', ')', '?', '*', '+', '.', '>' };

private static String regexEscape(char character) {
    for (char escapeChar : escapeChars) {
        if (character == escapeChar) {
            return "\\" + character;
        }
    }
    return String.valueOf(character);
}
0
brcolow

die Antwort ist zwar für Java, aber der Code kann leicht von dieser Kotlin-String-Erweiterung angepasst werden, die ich mir ausgedacht habe (angepasst von der @brcolow-Erweiterung):

private val escapeChars = charArrayOf(
    '<',
    '(',
    '[',
    '{',
    '\\',
    '^',
    '-',
    '=',
    '$',
    '!',
    '|',
    ']',
    '}',
    ')',
    '?',
    '*',
    '+',
    '.',
    '>'
)

fun String.escapePattern(): String {
    return this.fold("") {
      acc, chr ->
        acc + if (escapeChars.contains(chr)) "\\$chr" else "$chr"
    }
}

fun main() {
    println("(.*)".escapePattern())
}

druckt \(\.\*\)

überprüfen Sie es in Aktion hier https://pl.kotl.in/h-3mXZkNE

0
pocesar

Ich bin nicht sicher, ob ich deine Frage vollständig verstehe, aber ich denke, du solltest auf Matcher.quoteReplacement () schauen.

0
mkoryak