Ich möchte nur einen regulären Ausdruck aus einer möglichen Zeichenfolge erstellen.
var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);
Gibt es dafür eine eingebaute Methode? Wenn nicht, was benutzen die Leute? Ruby hat RegExp.escape
. Ich habe nicht das Gefühl, dass ich meine eigenen schreiben müsste, da draußen muss es etwas Standardisches geben. Vielen Dank!
javascript
regex
Lance Pollard
quelle
quelle
RegExp.escape
auf dem Laufenden halten, an denen gerade gearbeitet wird, und jeder, der glaubt, wertvolle Beiträge zu leisten, ist herzlich eingeladen, einen Beitrag zu leisten. Core-Js und andere Polyfills bieten es an.Antworten:
Die oben verlinkte Funktion ist unzureichend. Es kann nicht entkommen
^
oder$
(Anfang und Ende der Zeichenfolge) oder-
, das in einer Zeichengruppe für Bereiche verwendet wird.Verwenden Sie diese Funktion:
Während es auf den ersten Blick unnötig erscheint, macht das Escape
-
(sowie^
) die Funktion zum Escapezeichen für Zeichen, die in eine Zeichenklasse eingefügt werden sollen, sowie für den Hauptteil des regulären Ausdrucks.Durch Escaping
/
eignet sich die Funktion zum Escapezeichen von Zeichen, die in einem JS-Regex-Literal für eine spätere Auswertung verwendet werden sollen.Da es keinen Nachteil gibt, einem von beiden zu entkommen, ist es sinnvoll, zu entkommen, um breitere Anwendungsfälle abzudecken.
Und ja, es ist ein enttäuschender Fehler, dass dies nicht Teil von Standard-JavaScript ist.
quelle
/
überhauptquotemeta
(\Q
), Pythonre.escape
, PHPpreg_quote
, RubyRegexp.quote
...var e = /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g;
Dann lautet Ihre Funktion: Aufreturn s.replace(e, '\\$&');
diese Weise instanziieren Sie das RegExp nur einmal.RegExp.escape
deren Implementierung sich von Ihrer unterscheidet? Wäre es nicht besser, wenn diese Funktion an nichts gebunden wäre?Für alle, die lodash verwenden, ist seit v3.0.0 eine _.escapeRegExp- Funktion integriert:
Und für den Fall, dass Sie nicht die vollständige Lodash-Bibliothek benötigen , benötigen Sie möglicherweise genau diese Funktion !
quelle
escapeRegExp
Funktion benötigen können.Die meisten Ausdrücke hier lösen einzelne spezifische Anwendungsfälle.
Das ist okay, aber ich bevorzuge einen "immer funktionierenden" Ansatz.
Dadurch wird eine Literalzeichenfolge für eine der folgenden Verwendungen in regulären Ausdrücken "vollständig entzogen":
new RegExp(regExpEscape(str))
new RegExp('[' + regExpEscape(str) + ']')
new RegExp('x{1,' + regExpEscape(str) + '}')
Abgedeckte Sonderzeichen:
-
: Erstellt einen Zeichenbereich in einer Zeichenklasse.[
/]
: Startet / beendet eine Zeichenklasse.{
/}
: Startet / beendet einen Nummerierungsspezifizierer.(
/)
: Startet / beendet eine Gruppe.*
/+
/?
: Gibt an Wiederholungstyp..
: Entspricht einem beliebigen Zeichen.\
: Entkommt Zeichen und startet Entitäten.^
: Gibt den Beginn der Übereinstimmungszone an und negiert die Übereinstimmung in einer Zeichenklasse.$
: Gibt das Ende der Übereinstimmungszone an.|
: Gibt den Wechsel an.#
: Gibt einen Kommentar im freien Abstand an.\s
: Im Freiraummodus ignoriert.,
: Trennt Werte im Nummerierungsspezifizierer./
: Startet oder beendet den Ausdruck.:
: Vervollständigt spezielle Gruppentypen und einen Teil der Zeichenklassen im Perl-Stil.!
: Negiert die Gruppe mit der Breite Null.<
/=
: Teil der Gruppenspezifikationen mit der Breite Null.Anmerkungen:
/
ist in keinem Geschmack des regulären Ausdrucks unbedingt erforderlich. Es schützt jedoch für den Fall, dass jemand (Schauder) dies tuteval("/" + pattern + "/");
.,
stellt sicher, dass die Zeichenfolge, wenn sie im numerischen Bezeichner eine Ganzzahl sein soll, ordnungsgemäß einen RegExp-Kompilierungsfehler verursacht, anstatt stillschweigend falsch zu kompilieren.#
und\s
müssen nicht in JavaScript maskiert werden, sondern in vielen anderen Varianten. Sie werden hier maskiert, falls der reguläre Ausdruck später an ein anderes Programm übergeben wird.Wenn Sie den regulären Ausdruck auch gegen mögliche Ergänzungen der Funktionen der JavaScript-Regex-Engine zukunftssicher machen müssen, empfehle ich die Verwendung des paranoideren Ausdrucks:
Diese Funktion entgeht jedem Zeichen mit Ausnahme derjenigen, die ausdrücklich garantiert nicht für die Syntax in zukünftigen Varianten regulärer Ausdrücke verwendet werden.
Betrachten Sie diesen Randfall für wirklich sanitäre Menschen:
Dies sollte in JavaScript gut kompiliert werden können, in einigen anderen Varianten jedoch nicht. Wenn beabsichtigt wird, zu einem anderen Geschmack überzugehen, sollte der Nullfall von
s === ''
unabhängig überprüft werden, wie folgt:quelle
/
muss nicht in der[...]
Zeichenklasse maskiert werden.Das Mozilla Developer Network-Handbuch für reguläre Ausdrücke bietet diese Escape-Funktion:
quelle
=
ist nicht mehr enthalten.Im Autocomplete-Widget von jQueryUI (Version 1.9.1) wird ein etwas anderer regulärer Ausdruck verwendet (Zeile 6753). Hier ist der reguläre Ausdruck in Kombination mit dem @ bbince-Ansatz.
quelle
,
(was kein Metazeichen ist)#
und Leerzeichen, die nur im Freiraummodus von Bedeutung sind (der von JavaScript nicht unterstützt wird). Sie machen es jedoch richtig, dem Schrägstrich nicht zu entkommen.$.ui.autocomplete.escapeRegex(myString)
.Nichts sollte Sie davon abhalten, jedem nicht alphanumerischen Zeichen zu entkommen:
Sie verlieren dabei ein gewisses Maß an Lesbarkeit, gewinnen
re.toString()
aber viel Einfachheit (und Sicherheit).Nach ECMA-262, auf der einen Seite, sind reguläre Ausdrücke „Syntaxzeichen“ immer nicht-alphanumerische Zeichen, so dass das Ergebnis ist sicher, und ein speziellen Escape - Sequenzen (
\d
,\w
,\n
) sind immer alphanumerische , so dass keine falsche Steuer entweicht produziert werden .quelle
.replace(/[^\w]/g, '\\$&')
würde das genauso funktionieren.new RegExp('🍎'.replace(/(?=\W)/g, '\\'), 'u')
Ausnahme aus, da\W
jede Codeeinheit eines Ersatzpaares separat übereinstimmt, was zu ungültigen Escape-Codes führt..replace(/\W/g, "\\$&");
Es gibt einen ES7-Vorschlag für RegExp.escape unter https://github.com/benjamingr/RexExp.escape/. Eine Polyfüllung finden Sie unter https://github.com/ljharb/regexp.escape .
quelle
Dies ist eine kürzere Version.
Dazu gehört auch das Nicht-Meta - Zeichen
%
,&
,'
, und,
, aber die JavaScript RegExp - Spezifikation ermöglicht dies.quelle
.
wird vermisst. Und()
. Oder nicht?[-^
ist komisch. Ich erinnere mich nicht, was da ist.XRegExp hat eine Escape-Funktion:
XRegExp.escape('Escaped? <.>'); // -> 'Escaped\?\ <\.>'
Mehr unter: http://xregexp.com/api/#escape
quelle
Anstatt nur Zeichen zu maskieren, die Probleme in Ihrem regulären Ausdruck verursachen (z. B. eine schwarze Liste), sollten Sie stattdessen eine Whitelist verwenden. Auf diese Weise wird jedes Zeichen als verdorben betrachtet, sofern es nicht übereinstimmt.
Nehmen Sie für dieses Beispiel den folgenden Ausdruck an:
Diese Whitelist enthält Buchstaben, Zahlen und Leerzeichen:
Kehrt zurück:
Dies kann Zeichen entkommen, die nicht entkommen müssen, aber dies behindert Ihren Ausdruck nicht (möglicherweise einige geringfügige Zeitstrafen - aber es lohnt sich aus Sicherheitsgründen).
quelle
quelle
Die Funktionen in den anderen Antworten sind übertrieben, um ganze reguläre Ausdrücke zu maskieren (sie können nützlich sein, um Teile regulärer Ausdrücke zu maskieren, die später zu größeren regulären Ausdrücken verkettet werden).
Wenn Sie eine ganze regexp zu entkommen und wird mit ihnen geschehen, die Metazeichen zitiert , die entweder eigenständig sind (
.
,?
,+
,*
,^
,$
,|
,\
) oder beginnt , etwas ((
,[
,{
) ist alles , was Sie brauchen:Und ja, es ist enttäuschend, dass JavaScript keine solche Funktion hat.
quelle
(text)next
und fügen sie ein in:(?:
+ Eingabe +)
. Ihre Methode gibt die resultierende Zeichenfolge aus,(?:\(text)next)
die nicht kompiliert werden kann. Beachten Sie, dass dies eine ziemlich vernünftige Einfügung ist, nicht irgendeine verrückte wiere\
+ Eingabe +re
(in diesem Fall kann der Programmierer beschuldigt werden, etwas Dummes getan zu haben)\
sollte maskiert werden, da Ihre Regex\w
intakt bleibt. Außerdem scheint JavaScript kein Nachlaufen zuzulassen)
, zumindest ist dies der Grund, warum Firefox Fehler auslöst.)
Ein anderer (viel sicherer) Ansatz besteht darin, alle Zeichen (und nicht nur einige spezielle Zeichen, die wir derzeit kennen) mit dem Unicode-Escape-Format zu maskieren
\u{code}
:Bitte beachten Sie, dass Sie die bestehen müssen
u
Flag übergeben müssen, damit diese Methode funktioniert:quelle
Es gab und wird nur 12 Metazeichen geben, die maskiert werden müssen
, um als Literal betrachtet zu werden.
Es spielt keine Rolle, was mit der maskierten Zeichenfolge gemacht wird, die in einen ausgeglichenen
Regex-Wrapper eingefügt und angehängt wird.
Ersetzen Sie damit einen String
quelle
]
?