603 Stimmen

Gibt es eine RegExp.escape Funktion in JavaScript?

Ich möchte einfach einen regulären Ausdruck aus jedem möglichen String erstellen.

var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);

Gibt es dafür eine integrierte Methode? Wenn nicht, was verwenden die Leute? Ruby hat RegExp.escape. Ich habe nicht das Gefühl, dass ich meinen eigenen schreiben muss, es muss doch etwas Standardmäßiges geben.

18 Stimmen

Ich wollte euch feine Leute nur darüber informieren, dass RegExp.escape derzeit bearbeitet wird und jeder, der meint, wertvolle Beiträge leisten zu können, ist herzlich eingeladen, mitzuwirken. core-js und andere Polyfills bieten es an.

8 Stimmen

Gemäß dem aktuellen Update dieser Antwort wurde dieser Vorschlag abgelehnt: Siehe das Problem

1 Stimmen

Ja, ich glaube, dass @BenjaminGruenbaum derjenige sein könnte, der den Vorschlag vorgebracht hat. Ich habe versucht, Codebeispiele und das es-shim npm-Modul in einer Antwort auf Stack Overflow hier einzufügen: [ stackoverflow.com/a/63838890/5979634 ], weil der Vorschlag leider abgelehnt wurde. Hoffentlich ändern sie ihre Meinung oder jemand implementiert 'Template-Tags', bevor ich in Rente gehe.

776voto

bobince Punkte 512550

Die in einer anderen Antwort verlinkte Funktion ist unzureichend. Sie versäumt es, ^ oder $ (Anfang und Ende eines Strings) oder - zu escapen, was in einer Zeichenklasse für Bereiche verwendet wird.

Verwenden Sie diese Funktion:

function escapeRegex(string) {
    return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, '\\$&');
}

Auf den ersten Blick mag es unnötig erscheinen, - (sowie ^) zu escapen, aber dies macht die Funktion geeignet, um Zeichen für die Einfügung in eine Zeichenklasse sowie den Körper des Regex zu escapen.

Das Escapen von / macht die Funktion geeignet, um Zeichen zu escapen, die in einem JavaScript Regex-Literal für spätere Auswertung verwendet werden sollen.

Da es keinen Nachteil gibt, eines von beiden zu escapen, macht es Sinn, zu escapen, um breitere Anwendungsfälle abzudecken.

Und ja, es ist enttäuschend, dass dies nicht Teil von Standard-JavaScript ist.

4 Stimmen

@spinningarrow: Es repräsentiert den gesamten übereinstimmenden String, ähnlich wie 'Gruppe 0' in vielen anderen Regex-Systemen. doc

2 Stimmen

Ich glaube, die ursprüngliche Antwort war korrekt, bevor die Bearbeitung vorgenommen wurde. Ich bin mir ziemlich sicher, dass es nicht notwendig ist, den Schrägstrich innerhalb der Zeichenklasse zu escapen. Es scheint keinen Schaden anzurichten, aber es ist nicht erforderlich.

23 Stimmen

Eigentlich müssen wir / überhaupt nicht escapen.

190voto

gustavohenke Punkte 39617

Für alle, die Lodash verwenden, ist seit Version v3.0.0 eine _.escapeRegExp Funktion integriert:

_.escapeRegExp('[lodash](https://lodash.com/)');
//  '\[lodash\]\(https:\/\/lodash\.com\/\)'

Und für den Fall, dass Sie nicht die gesamte Lodash-Bibliothek benötigen, können Sie nur diese Funktion requiren!

8 Stimmen

Es gibt sogar ein npm-Paket nur dafür! npmjs.com/package/lodash.escaperegexp

0 Stimmen

Achte darauf, dass die escapeRegExp-Funktion von lodash auch \x3 am Anfang des Strings hinzufügt, bin mir nicht ganz sicher, warum.

2 Stimmen

Dies importiert eine Menge Code, der wirklich nicht für so einfache Dinge benötigt wird. Verwenden Sie die Antwort von bobince... funktioniert für mich und spart so viele Bytes im Vergleich zur lodash-Version!

55voto

Pi Marillion Punkte 3697

Die meisten Ausdrücke hier lösen spezifische Einzelfälle.

Das ist in Ordnung, aber ich bevorzuge einen Ansatz, der "immer funktioniert".

function regExpEscape(literal_string) {
    return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}

Dies wird einen literalen String für folgende Verwendungen in regulären Ausdrücken "vollständig escapen":

  • Einfügen in einen regulären Ausdruck. z.B. new RegExp(regExpEscape(str))
  • Einfügen in eine Zeichenklasse. z.B. new RegExp('[' + regExpEscape(str) + ']')
  • Einfügen in einen Integer-Zähl-Spezifikator. z.B. new RegExp('x{1,' + regExpEscape(str) + '}')
  • Ausführung in nicht-JavaScript-regulären Ausdrucks-Engines.

Behandelte Sonderzeichen:

  • -: Erzeugt ein Zeichenbereich in einer Zeichenklasse.
  • [ / ]: Startet / beendet eine Zeichenklasse.
  • { / }: Startet / beendet einen Nummerierungsspezifikator.
  • ( / ): Startet / beendet eine Gruppe.
  • * / + / ?: Spezifiziert den Wiederholungstyp.
  • .: Passt auf jedes Zeichen.
  • \: Escapiert Zeichen und startet Entitäten.
  • ^: Spezifiziert den Start des Übereinstimmungsbereichs und negiert das Matchen in einer Zeichenklasse.
  • $: Spezifiziert das Ende des Übereinstimmungsbereichs.
  • |: Spezifiziert Alternation.
  • #: Spezifiziert einen Kommentar im free-spacing-Modus.
  • \s: Im free-spacing-Modus ignoriert.
  • ,: Trennt Werte im Nummerierungsspezifikator.
  • /: Startet oder beendet den Ausdruck.
  • :: Vollendet spezielle Gruppentypen und Teil von Perl-style Zeichenklassen.
  • !: Negiert Nullbreiten-Gruppe.
  • < / =: Teil der Nullbreiten-Gruppenspezifikationen.

Anmerkungen:

  • / ist in keiner Variante eines regulären Ausdrucks strikt notwendig. Es schützt jedoch, falls jemand (schauder) dies tut: eval("/" + pattern + "/");.
  • , stellt sicher, dass, wenn der String integer im numerischen Spezifikator sein soll, es richtig einen RegExp-Kompilierungsfehler verursacht anstatt stillschweigend falsch zu kompilieren.
  • # und \s müssen in JavaScript nicht escapet werden, aber in vielen anderen Varianten schon. Sie sind hier escapet, falls der reguläre Ausdruck später an ein anderes Programm übergeben wird.

Wenn Sie den regulären Ausdruck auch gegen potenzielle Ergänzungen der JavaScript-Regex-Engine-Funktionen zukunftssicher machen möchten, empfehle ich die sicherere Variante:

function regExpEscapeFuture(literal_string) {
    return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&');
}

Diese Funktion escapet jedes Zeichen, außer denen, die explizit garantiert nicht für die Syntax in zukünftigen regulären Ausdrucksvarianten verwendet werden.


Für diejenigen, die wirklich auf Reinlichkeit bedacht sind, erwägen Sie diesen Spezialfall:

var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');

Dies sollte in JavaScript gut kompilieren, aber in einigen anderen Varianten nicht. Wenn die Absicht besteht, es an eine andere Variante weiterzugeben, sollte der Nullfall von s === '' unabhängig überprüft werden, wie folgt:

var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');

1 Stimmen

Der / muss nicht in der [...] Zeichenklasse maskiert werden.

1 Stimmen

Die meisten davon müssen nicht maskiert werden. "Erstellt einen Zeichenbereich in einer Zeichenklasse" - du befindest dich nie innerhalb einer Zeichenklasse innerhalb des Strings. "Gibt einen Kommentar im Free-Spacing-Modus an, wird im Free-Spacing-Modus ignoriert" - nicht unterstützt in JavaScript. "Trennt Werte im Numerationsspezifikator" - du befindest dich nie im Numerationsspezifikator innerhalb des Strings. Außerdem kannst du keinen beliebigen Text innerhalb der Nennvorschrift schreiben. "Startet oder beendet einen Ausdruck" - kein Bedarf an Escapen. Eval ist kein Fall, da es viel mehr Escapen erfordern würde. [wird im nächsten Kommentar fortgesetzt]

0 Stimmen

"Vervollständigt spezielle Gruppentypen und ist Teil von Perl-Style- Zeichenklassen" - scheint nicht in JavaScript verfügbar zu sein. "Negiert Null-Breite-Gruppe, Teil von Null-Breite-Gruppenspezifikationen" - Man hat nie Gruppen innerhalb des Strings.

46voto

quietmint Punkte 13182

Leitfaden des Mozilla Developer Network zu regulären Ausdrücken bietet diese Escaping-Funktion an:

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& bedeutet den gesamten übereinstimmenden String
}

0 Stimmen

@DanDascalescu Du hast recht. Die MDN-Seite wurde aktualisiert und = ist nicht mehr enthalten.

23voto

Pierluc SS Punkte 3038

Im Autocomplete-Widget von jQuery UI (Version 1.9.1) wird eine leicht abweichende reguläre Ausdruck verwendet (Zeile 6753), hier ist der reguläre Ausdruck in Kombination mit bobinces Ansatz.

RegExp.escape = function( value ) {
     return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}

4 Stimmen

Der einzige Unterschied besteht darin, dass sie , (das kein Metazeichen ist), # und Leerzeichen escapen, die nur im freien Spacing-Modus von Bedeutung sind (der von JavaScript nicht unterstützt wird). Sie haben jedoch Recht, den Schrägstrich nicht zu escapen.

20 Stimmen

Wenn Sie die Implementierung von jQuery UI wiederverwenden möchten anstelle des lokalen Einfügens des Codes, verwenden Sie $.ui.autocomplete.escapeRegex(myString).

3 Stimmen

Lodash hat auch dies, _. escapeRegExp und npmjs.com/package/lodash.escaperegexp

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X