14 Stimmen

SQL LIKE in JavaScript emulieren

Wie kann ich das SQL-Schlüsselwort emulieren? LIKE in JavaScript?

Für diejenigen unter Ihnen, die nicht wissen, was LIKE ist eine sehr einfache Regex, die nur die Wildcards unterstützt % der auf 0 oder mehr Zeichen passt, und _ die genau einem Zeichen entspricht.

Es ist jedoch nicht nur möglich, so etwas zu tun:

var match = new RegEx(likeExpr.replace("%", ".*").replace("_", ".")).exec(str) != null;

...weil das Muster Punkte, Sterne und andere spezielle Regex-Zeichen enthalten kann.

12voto

Chris Van Opstal Punkte 34697

Was Sie haben, wird funktionieren, solange Sie zuerst die Regex-Zeichen in Ihrem Muster entschlüsseln. Im Folgenden finden Sie ein Beispiel aus Simon Willison's Blog :

RegExp.escape = function(text) {
  if (!arguments.callee.sRE) {
    var specials = [
      '/', '.', '*', '+', '?', '|',
      '(', ')', '[', ']', '{', '}', '\\'
    ];
    arguments.callee.sRE = new RegExp(
      '(\\' + specials.join('|\\') + ')', 'g'
    );
  }
  return text.replace(arguments.callee.sRE, '\\$1');
}

Sie könnten Ihren Code dann wie folgt implementieren:

likeExpr = RegExp.escape(likeExpr);
var match = new RegEx(likeExpr.replace("%", ".*").replace("_", ".")).exec(str) != null;

7voto

Steven de Salas Punkte 19903

Ich habe nach einer Antwort auf dieselbe Frage gesucht und bin nach dem Lesen von Kips Antwort auf Folgendes gestoßen:

String.prototype.like = function(search) {
    if (typeof search !== 'string' || this === null) {return false; }
    // Remove special chars
    search = search.replace(new RegExp("([\\.\\\\\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:\\-])", "g"), "\\$1");
    // Replace % and _ with equivalent regex
    search = search.replace(/%/g, '.*').replace(/_/g, '.');
    // Check matches
    return RegExp('^' + search + '$', 'gi').test(this);
}

Sie können es dann wie folgt verwenden (beachten Sie, dass Groß-/Kleinschreibung ignoriert wird):

var url = 'http://www.mydomain.com/page1.aspx';
console.log(url.like('%mydomain.com/page_.asp%')); // true

ANMERKUNG 29/11/2013: Aktualisiert mit RegExp.test() Leistungsverbesserung wie in Lucios Kommentar unten.

3voto

JohnLock Punkte 331

Eine alte Frage, auf die es eigentlich keine guten Antworten gibt. TSQL LIKE-Ausdrücke können mit eckigen Klammern versehene Abschnitte enthalten, die bereits fast gültige reguläre Ausdrücke sind und einen Abgleich ermöglichen % y _ . Z.B.:

'75%' LIKE '75[%]'
'[foo]' LIKE '[[]foo]' -- ugh

Hier ist meine Funktion zur Umwandlung eines LIKE-Ausdrucks in einen RegExp. Die Eingabe wird in Abschnitte mit eckigen und nicht eckigen Klammern unterteilt. Die Abschnitte mit eckigen Klammern müssen nur mit Backslash escaped werden und die Abschnitte ohne eckige Klammern werden vollständig escaped, während die % y _ Direktiven werden in reguläre Ausdrücke umgewandelt.

const likeRegExp = (expression, caseSensitive = false) =>
    new RegExp(`^${
        expression.split(/(\[.+?\])/g)
        .map((s, i) => i % 2 ?
            s.replace(/\\/g, '\\\\') :
            s.replace(/[-\/\\^$*+?.()|[\]{}%_]/g, m => {
                switch(m) {
                    case '%': return '.*';
                    case '_': return '.';
                    default: return `\\${m}`;
                }
            })
        ).join('')
    }$`, caseSensitive ? '' : 'i');

2voto

Kip Punkte 102702

Hier ist eine Funktion, die ich verwende, basierend auf PHPs preg_quote-Funktion :

function regex_quote(str) {
  return str.replace(new RegExp("([\\.\\\\\\+\\*\\?\\[\\^\\]\\$\\(\\)\\{\\}\\=\\!\\<\\>\\|\\:\\-])", "g"), "\\$1");
}

Ihre Zeile würde also jetzt lauten:

var match = new RegEx(regex_quote(likeExpr).replace("%", ".*").replace("_", ".")).exec(str) != null;

1voto

Joel Coehoorn Punkte 377088

Wenn Sie eine Regex verwenden möchten, können Sie jedes Zeichen der Zeichenkette in eckige Klammern einschließen. Dann müssen Sie nur wenige Zeichen auslassen.

Eine bessere Möglichkeit wäre jedoch, die Zielzeichenketten so zu kürzen, dass die Länge mit der Suchzeichenkette übereinstimmt, und auf Gleichheit zu prüfen.

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