416 Stimmen

Umwandlung der Benutzereingabe in einen regulären Ausdruck

Ich entwickle ein Prüfprogramm für reguläre Ausdrücke in HTML und JavaScript. Der Benutzer gibt einen Regex, eine Zeichenkette, ein und wählt die Funktion, mit der er testen möchte (z.B. Suchen, Vergleichen, Ersetzen, etc.) per Radiobutton und das Programm zeigt die Ergebnisse an, wenn diese Funktion mit den angegebenen Argumenten ausgeführt wird. Natürlich gibt es zusätzliche Textfelder für die zusätzlichen Argumente zum Ersetzen und so weiter.

Mein Problem ist es, die Zeichenfolge vom Benutzer zu erhalten und sie in einen regulären Ausdruck zu verwandeln. Wenn ich sage, dass sie nicht brauchen, um zu haben // um den eingegebenen Regex herum, dann können sie keine Flags setzen, wie g y i . Sie müssen also über die // um den Ausdruck herum, aber wie kann ich diese Zeichenfolge in einen Regex umwandeln? Sie kann kein Literal sein, da sie eine Zeichenkette ist, und ich kann sie nicht an den RegExp-Konstruktor übergeben, da sie keine Zeichenkette ohne das // 's. Gibt es eine andere Möglichkeit, eine Benutzereingabe in eine Regex zu verwandeln? Muss ich die Zeichenkette und die Flags der Regex mit dem // Wie kann man sie dann anders konstruieren? Sollte ich sie eine Zeichenkette eingeben lassen und dann die Flaggen separat eingeben?

12voto

Richie Bendall Punkte 5294

Versuchen Sie es mit der folgenden Funktion:

const stringToRegex = str => {
    // Main regex
    const main = str.match(/\/(.+)\/.*/)[1]

    // Regex options
    const options = str.match(/\/.+\/(.*)/)[1]

    // Compiled regex
    return new RegExp(main, options)
}

Sie können ihn wie folgt verwenden:

"abc".match(stringToRegex("/a/g"))
//=> ["a"]

6voto

Tofandel Punkte 2230

Hier ist meine One-Liner-Funktion, die benutzerdefinierte Begrenzungszeichen und ungültige Flags behandelt

function stringToRegex(s, m) {
  return (m = s.match(/^([\/~@;%#'])(.*?)\1([gimsuy]*)$/)) ? new RegExp(m[2], m[3].split('').filter((i, p, s) => s.indexOf(i) === p).join('')) : new RegExp(s);
}

console.log(stringToRegex('/(foo)?\/bar/i'));
console.log(stringToRegex('#(foo)?\/bar##gi')); //Custom delimiters
console.log(stringToRegex('#(foo)?\/bar##gig')); //Duplicate flags are filtered out
console.log(stringToRegex('/(foo)?\/bar')); // Treated as string
console.log(stringToRegex('gig')); // Treated as string

3voto

Stephan202 Punkte 57491

Ich schlage vor, dass Sie auch separate Kontrollkästchen oder ein Textfeld für die Sonderkennzeichen hinzufügen. Auf diese Weise ist klar, dass der Benutzer keine weiteren Angaben machen muss. // 's. Im Falle einer Ersetzung ist Folgendes anzugeben dos Textfelder. Das wird Ihr Leben sehr viel einfacher machen.

Warum? Weil sonst einige Benutzer // und andere nicht. Und einige werden einen Syntaxfehler machen. Dann, nachdem Sie die // Wenn Sie die Regex nicht in den Regex einfügen, kann es passieren, dass Sie eine syntaktisch gültige Regex erhalten, die nicht dem entspricht, was der Benutzer beabsichtigt hat, was zu einem seltsamen Verhalten führt (aus der Sicht des Benutzers).

2voto

kofifus Punkte 14007

Dies funktioniert auch, wenn die Zeichenfolge ungültig ist oder keine Flaggen usw. enthält:

function regExpFromString(q) {
  let flags = q.replace(/.*\/([gimuy]*)$/, '$1');
  if (flags === q) flags = '';
  let pattern = (flags ? q.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1') : q);
  try { return new RegExp(pattern, flags); } catch (e) { return null; }
}

console.log(regExpFromString('\\bword\\b'));
console.log(regExpFromString('\/\\bword\\b\/gi'));

1voto

Pim Jager Punkte 31389

Sie können mit Hilfe von Kontrollkästchen nach Flaggen fragen und dann etwas wie folgt tun:

var userInput = formInput;
var flags = '';
if(formGlobalCheckboxChecked) flags += 'g';
if(formCaseICheckboxChecked) flags += 'i';
var reg = new RegExp(userInput, flags);

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