Ich versuche, eine Anwendung zu erstellen, die eine Nachrichtenvorlage mit einer Nachricht vergleicht, die ein Benutzer senden möchte. Ich verwende Java Regex zum Abgleichen der Nachricht. Die Vorlage / Nachricht kann Sonderzeichen enthalten.
Wie würde ich die vollständige Liste der Sonderzeichen erhalten, die maskiert 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?
\Q
und\E
] wird als entkommen betrachtet" - mit Ausnahme anderer\Q
und\E
(die möglicherweise innerhalb des ursprünglichen regulären Ausdrucks auftreten können). Es ist also besser,Pattern.quote
wie hier vorgeschlagen zu verwenden und das Rad nicht neu zu erfinden.\.[]{}()<>*+-=!?^$|
]
und}
) müssen erst nach dem Öffnen des gleichen Klammertyps ausgeblendet werden.[]
Klammern funktionieren einige Zeichen (wie+
und-
) manchmal ohne Flucht.quelle
-
innerhalb[]
kann nicht immer funktionieren , da es Bereiche zu definieren , verwendet wird. Es ist sicherer, ihm zu entkommen. Zum Beispiel die Muster[-]
und[-)]
stimmen mit der Zeichenfolge überein,-
aber nicht mit[(-)]
.Um zu entkommen, können Sie dies einfach aus Java 1.5 verwenden :
Sie werden genau das Wort finden
$test
quelle
Laut der Dokumentationsseite für String-Literale / Metazeichen sind dies:
<([{\^-=$!|]})?*+.>
Es wäre auch cool, diese Liste irgendwo im Code zu haben, aber ich weiß nicht, wo das sein könnte ...
quelle
String escaped = tnk.replaceAll("[\\<\\(\\[\\{\\\\\\^\\-\\=\\$\\!\\|\\]\\}\\)\\?\\*\\+\\.\\>]", "\\\\$0");
s.replaceAll("[\\W]", "\\\\$0")
wobei\W
Nicht-Wort-Zeichen bezeichnet werden.Auf @ Sorins Vorschlag der Java Pattern-Dokumente hin sieht es so aus, als wären Zeichen, denen man entkommen muss, mindestens:
quelle
String escaped = regexString.replaceAll("([\\\\\\.\\[\\{\\(\\*\\+\\?\\^\\$\\|])", "\\\\$1");
)
muss auch maskiert werden, und je nachdem, ob Sie sich innerhalb oder außerhalb einer Zeichenklasse befinden, müssen möglicherweise mehr Zeichen maskiert werden. In diesem Fall istPattern.quote
es recht gut, eine Zeichenfolge für die Verwendung innerhalb und außerhalb der Zeichenklasse zu maskieren.Ich schlage Folgendes vor, um die Liste der für RegExp speziellen Zeichen klar in ihrer eigenen Zeichenfolge aufzulisten und zu vermeiden, dass Tausende von "\\" visuell analysiert werden müssen. Das scheint für mich ziemlich gut zu funktionieren:
quelle
Die
Pattern.quote(String s)
Art macht, was Sie wollen. Es lässt jedoch ein wenig zu wünschen übrig; Es entgeht nicht den einzelnen Zeichen, sondern umschließt nur die Zeichenfolge 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 Java-Ausdruck zu umgehen:
Warum funktioniert das? Nun, die Dokumentation für
Pattern
besagt ausdrücklich, dass es zulässig ist, nicht alphabetische Zeichen zu maskieren, die nicht unbedingt maskiert werden müssen:Zum Beispiel
;
ist kein Sonderzeichen in einem regulären Ausdruck. Wenn Sie jedoch entkommen,Pattern
wird immer noch\;
als interpretiert;
. Hier noch ein paar Beispiele:>
wird\>
was äquivalent zu ist>
[
wird\[
was ist die entkommene Form von[
8
ist immer noch8
.\)
wird\\\)
was die entkommenen Formen von\
und(
verkettet ist.Hinweis: Der Schlüssel ist die Definition von "nicht alphabetisch", was in der Dokumentation wirklich "Nicht- Wort " -Zeichen oder Zeichen außerhalb des Zeichensatzes bedeutet
[a-zA-Z_0-9]
.quelle
Auf der anderen Seite der Medaille sollten Sie einen Regex ohne Zeichen verwenden, der so aussieht, wenn in Ihrem App-Kontext Sonderzeichen = allChars - Nummer - ABC - Leerzeichen stehen.
quelle
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 dem bereitgestellten @ brcolow):
druckt
\(\.\*\)
Überprüfen Sie es in Aktion hier https://pl.kotl.in/h-3mXZkNE
quelle
Angenommen, Sie haben und vertrauen (um maßgeblich zu sein) der Liste der von Java Regex verwendeten Escape-Zeichen (wäre schön, wenn diese Zeichen in einem Pattern-Klassenmitglied verfügbar gemacht würden), können Sie die folgende Methode verwenden, um das Zeichen zu maskieren, wenn dies tatsächlich erforderlich ist:
quelle