Javascript + Regex = Nichts, um Fehler zu wiederholen?

75

Ich bin neu bei Regex und versuche, es in eines meiner neuen Projekte einzubringen, um zu sehen, ob ich es lernen und zu meinem Repitoire an Fähigkeiten hinzufügen kann. Allerdings stoße ich hier auf eine Straßensperre.

Ich versuche zu sehen, ob die Benutzereingabe unzulässige Zeichen enthält, indem ich die .searchFunktion folgendermaßen verwende:

if (name.search("[\[\]\?\*\+\|\{\}\\\(\)\@\.\n\r]") != -1) {
    ...
}

Wenn ich jedoch versuche, die Funktion auszuführen, in der diese Zeile enthalten ist, wird für diese bestimmte Zeile der folgende Fehler ausgegeben:

Uncaught SyntaxError: Invalid regular expression: /[[]?*+|{}\()@.

]/: Nothing to repeat

Ich kann für mein ganzes Leben nicht sehen, was mit meinem Code nicht stimmt. Kann mich jemand in die richtige Richtung weisen?

esqew
quelle

Antworten:

108

Sie müssen die umgekehrten Schrägstriche verdoppeln, um die Sonderzeichen für reguläre Ausdrücke zu umgehen. Wie @Bohemian jedoch betont, werden die meisten dieser Backslashes nicht benötigt. Leider hat seine Antwort das gleiche Problem wie Ihre. Was Sie eigentlich wollen, ist:

Der Backslash wird von dem Code interpretiert, der die Zeichenfolge liest, anstatt an den Parser für reguläre Ausdrücke übergeben zu werden. Sie wollen:

"[\\[\\]?*+|{}\\\\()@.\n\r]"

Beachten Sie den vierfachen Backslash. Das ist definitiv nötig. Die an den Compiler für reguläre Ausdrücke übergebene Zeichenfolge ist dann mit der Zeichenfolge von @ Bohemian identisch und funktioniert ordnungsgemäß.

andrewdski
quelle
3
Übrigens wird das Vierfache nur in einigen langs benötigt; zB Java ja, Perl nicht
Bohemian
Ein ebenfalls angetroffener Duh-Moment, dem ich ebenfalls begegnet bin. Gut daran zu erinnern, dass Backslash zuerst von der Sprachsyntax und dann von RegExp interpretiert wird.
Enorl76
8

Aufbauend auf @Bohemian denke ich, dass der einfachste Ansatz darin besteht, nur ein Regex-Literal zu verwenden, z.

if (name.search(/[\[\]?*+|{}\\()@.\n\r]/) != -1) {
    // ... stuff ...
}

Regex-Literale sind nett, weil Sie dem Escape-Zeichen nicht entkommen müssen und einige IDEs ungültigen Regex hervorheben (sehr hilfreich für mich, da ich sie ständig vermassle).

NobodyMan
quelle
2

Erstens müssen in einer Charakterklasse die [...] meisten Charaktere nicht entkommen - sie sind nur Literale.

Ihr regulärer Ausdruck sollte also sein:

"[\[\]?*+|{}\\()@.\n\r]"

Das kompiliert für mich.

Böhmisch
quelle
@Icet funktionieren die anderen Antworten bei Ihnen nicht? Wenn nicht, welcher Eingang funktioniert "nicht"?
Bohemian
Zum Beispiel funktioniert +44 als Eingabe nicht. Diese Lösung funktioniert einwandfrei str.replace (/ [\ - [] \ / \ {\} () * \ + \? \. \\\ ^ \ $ \ |] / g, "\\ $ &");
Icet
0

Für Google-Reisende: Diese dumm nicht hilfreiche Fehlermeldung wird auch angezeigt, wenn Sie einen Typ +erstellen und den Regex-Operator verdoppeln :

In Ordnung:

\w+

Nicht Okay:

\w++
Tomáš Hübelbauer
quelle
-1

Nun, in meinem Fall musste ich eine Telefonnummer mit Hilfe von Regex testen und bekam den gleichen Fehler.

Invalid regular expression: /+923[0-9]{2}-(?!1234567)(?!1111111)(?!7654321)[0-9]{7}/: Nothing to repeat'

Was also der Fehler in meinem Fall war, war dieser +Operator nach /dem Beginn des regulären Ausdrucks. Das Einschließen des +Operators in eckige Klammern [+]und das erneute Senden der Anfrage funktionierten also wie ein Zauber.

Folgendes wird funktionieren:

/[+]923[0-9]{2}-(?!1234567)(?!1111111)(?!7654321)[0-9]{7}/

Diese Antwort kann für diejenigen hilfreich sein, die die gleiche Art von Fehler haben, aber ihre Chancen, den Fehler unter diesem Gesichtspunkt zu erhalten, wie meine! Prost :)

Aneeq Ahmad
quelle
Warum sind Sie dem Pluszeichen nicht einfach entkommen, anstatt es vollständig zu verschieben ...? ( \+)
esqew
Vielen Dank, dass ich @esqew eine andere verstehen ließ, aber ich habe eine andere Lösung :)
Aneeq Ahmad