it-swarm.com.de

Benutzereingabezeichenfolge in regulären Ausdruck konvertieren

Ich entwerfe einen Tester für reguläre Ausdrücke in HTML und JavaScript. Der Benutzer gibt einen regulären Ausdruck oder eine Zeichenfolge ein und wählt die zu testende Funktion (z. B. Suchen, Abgleichen, Ersetzen usw.) über das Optionsfeld aus. 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, die ersetzt werden müssen, und so weiter.

Mein Problem besteht darin, die Zeichenfolge vom Benutzer abzurufen und in einen regulären Ausdruck umzuwandeln. Wenn ich sage, dass sie keine // In der Regex haben müssen, die sie eingeben, können sie keine Flags wie g und i setzen. Sie müssen also die Zeichenfolge // Um den Ausdruck herum haben, aber wie kann ich diese Zeichenfolge in eine reguläre Zeichenfolge konvertieren? Es kann kein Literal sein, da es eine Zeichenfolge ist, und ich kann es nicht an den RegExp-Konstruktor übergeben, da es keine Zeichenfolge ohne die Zeichenfolge // Ist. Gibt es eine andere Möglichkeit, einen Benutzereingabestring in einen regulären Ausdruck umzuwandeln? Muss ich den String und die Flags des Regex mit dem // Analysieren und dann anders konstruieren? Soll ich sie eine Zeichenfolge eingeben lassen und dann die Flags separat eingeben?

308

Verwenden Sie den RegExp-Objektkonstruktor , um einen regulären Ausdruck aus einer Zeichenfolge zu erstellen:

var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;
572
Gumbo
var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);

oder

var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);
65
Anonymous

Hier ist ein Einzeiler: str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')

Ich habe es aus dem Escape-String-Regexp NPM-Modul.

Probieren Sie es aus:

escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
    return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}

console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/
15
Rivenfall

Verwenden Sie den JavaScript RegExp-Objektkonstruktor .

var re = new RegExp("\\w+");
re.test("hello");

Sie können Flags als zweites Zeichenfolgenargument an den Konstruktor übergeben. Einzelheiten finden Sie in der Dokumentation.

14
Ayman Hourieh

In meinem Fall war die Benutzereingabe manchmal von Trennzeichen umgeben und manchmal nicht. deshalb habe ich noch einen fall hinzugefügt ..

var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
    // the parsed pattern had delimiters and modifiers. handle them. 
    var regexp = new RegExp(regParts[1], regParts[2]);
} else {
    // we got pattern string without delimiters
    var regexp = new RegExp(inputstring);
}
9
staabm

Dies funktioniert auch, wenn die Zeichenfolge ungültig ist oder keine Flags 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'));
            
2
kofifus

Ich schlage vor, Sie fügen auch separate Kontrollkästchen oder ein Textfeld für die speziellen Flags hinzu. Auf diese Weise wird klar, dass der Benutzer keine // Hinzufügen muss. Geben Sie im Fall eines Ersetzens zwei Textfelder an. Dies wird Ihr Leben viel einfacher machen.

Warum? Denn ansonsten fügen einige Benutzer // Hinzu, während andere dies nicht tun. Und einige machen einen Syntaxfehler. Nachdem Sie die // Entfernt haben, kann es sein, dass Sie einen syntaktisch gültigen regulären Ausdruck erhalten, der nicht dem entspricht, was der Benutzer beabsichtigt hat. Dies führt zu seltsamem Verhalten (aus Sicht des Benutzers).

2
Stephan202

Dank früherer Antworten bietet dieser Block eine universelle Lösung zum Anwenden einer konfigurierbaren Zeichenfolge in eine RegEx .. zum Filtern von Text:

var permittedChars = '^a-z0-9 _,[email protected]+<>';
permittedChars = '[' + permittedChars + ']';

var flags = 'gi';
var strFilterRegEx = new RegExp(permittedChars, flags);

log.debug ('strFilterRegEx: ' + strFilterRegEx);

strVal = strVal.replace(strFilterRegEx, '');
// this replaces hard code solt:
// strVal = strVal.replace(/[^a-z0-9 _,[email protected]+]/ig, '');
1
Gene Bo

Sie können mithilfe von Kontrollkästchen nach Flags fragen und dann folgendermaßen vorgehen:

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

Wenn Sie wirklich einen String in einen regulären Ausdruck konvertieren möchten, verwenden Sie die folgende Funktion:

function String2Regex(s){return new RegExp(s.match(/\/(.+)\/.*/)[1], s.match(/\/.+\/(.*)/)[1]);}

Du kannst es so benutzen:

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

Als Referenz ist hier die formatierte und modernere Version:

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

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

  // Return compiled regex
  return new RegExp(main, options)
}
0
Richie Bendall