2009-08-21 9 views
6

JavaScriptでSQLキーワードLIKEをエミュレートするにはどうすればよいですか? LIKEが何であるかを知らない人のためにJavaScriptでSQL LIKEをエミュレートする

、それだけで0個以上の文字と一致し、_正確に1文字に一致するワイルドカード%を、サポートしている非常に単純な正規表現です。パターンは、ドット、星や他の特別な正規表現の文字が含まれている可能性があるので...

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

しかし、それはのような何かをするだけのことはできません。

+0

fyi-:結果()私はここに表示されていない機能である - ここで私は、ツール上の任意の結果を表示しないようにしたい、連絡先や自宅ページ'.exec'" – Kip

+0

@ C.ba rlow:編集時に古い "edit:.. blah"マークを削除することを躊躇しないでください。「最高のスタンドアロン問題」を目指す。編集履歴はすべて見ることができるため、解説を続ける必要はありません。 :) – sarnold

+0

@sarnold Gotcha!ガイダンスをありがとう! –

答えて

6

あなたが持っているものは、パターンの正規表現文字を最初にエスケープしている限り動作します。以下は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'); 
} 

あなたはその後、としてあなたのコードを実装することができます:ここでPHP's preg_quote functionに基づいて、私が使用して機能、だ

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

'RegExp.like = function(text){return new RegExp("^"+(RegExp.escape(text).replace(/%/ g、"。* ")。/g、 "。"))+ "$"); } '彼のためにもう少し再利用可能かもしれない。 – gnarf

+0

'Regex.escape'の実装は非常に残酷です。 まず、 'arguments.callee'オカレンスは現代的なブラウザのいくつかの最適化を防ぎます(そして、ES5厳格では推奨されません)。可能であれば避けてください。 第2に、不要なエスケープ文字があり、その代わりに文字クラスに配置することができます。 Prototype.jsで使用している、より小さい(そして最も可能性が高い)バージョン - 'RegExp.escape = function(str){return str.replace(/([。* +?^:!:$ {} )| [\] \/\\])/ g、 '\\ $ 1'); }; ' – kangax

1

正規表現を使用する場合は、文字列の各文字を角かっこで囲むことができます。それから、あなたは逃げる少数のキャラクターしか持っていません。

しかし、より良いオプションは、長さが検索文字列と一致するようにターゲット文字列を切り捨てて、等価性をチェックすることです。

2

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

だからあなたの行はなり現在:

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

私が答え同じ質問を探しているとキップの返信読んだ後、この思い付いた:次のようにあなたがそれを使用することができます

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); 
} 

を(それは大文字/小文字を無視することに注意してください):

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

注記29/11/2013:下記のLuciosコメントごとにRegExp.test()のパフォーマンス改善で更新されました。

+0

の代わりに!! this.match(...、this.testを使用しないでください(...? –

+0

)@LucioM.Tato、x.test()メソッドは、StringではなくRegExpインスタンス用ですオブジェクト.. [http://www.w3schools.com/jsref/jsref_regexp_test.asp] (http://www.w3schools.com/jsref/jsref_regexp_test.asp) –

+0

私は申し訳ありません私は明確ではありませんでした。 .test(より良い性能)を使用する代わりに、マッチ配列(高価な正規表現)を取得する必要があります:return new RegExp(...)。test(this);配列やヌルを二重否定によってブール値に変換するのではなく.. http://stackoverflow.com/questions/10940137/regex-test-vs-string-match-to-know-if-a-string-matches-a-regular-expression –

0

Chris Van Opstalの答えでは、置き換えの代わりにreplaceAllを使用して、 '%'と '_'のすべての出現箇所を置き換える必要があります。でReplaceAllを行う方法に リファレンス - here

0

ジョニー最近ここに来るが、これは、私は、デフォルトのページの後に結果を示す特定のページを避けるために、私のスパページのためにそれを使用する私の作品:さ

function like(haystack,needle){ 
    needle = needle.split(','); 
    var str = haystack.toLowerCase(); 
    var n = -1; 
    for(var i=0;i<needle.length;i++){ 
     n = str.search(needle[i]); 
     if(n > -1){ 
      return n; 
     } 
    } 
return n; 
} 

使い方 - あなたは、「前に閉じ括弧が欠落している、あなたのサンプルコードで

var n = like($data,'tools,contact,home'); 
//~ alert(n); 
if(n < 0){// does not match anything in the above string 
    results($data); 
}