Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/425.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在JavaScript中模拟类SQL_Javascript_Sql_Regex_Sql Like - Fatal编程技术网

在JavaScript中模拟类SQL

在JavaScript中模拟类SQL,javascript,sql,regex,sql-like,Javascript,Sql,Regex,Sql Like,如何在JavaScript中模拟SQL关键字如 对于那些不知道什么是的人来说,这是一个非常简单的正则表达式,它只支持通配符%,匹配0个或多个字符,以及只匹配一个字符 但是,不可能只执行以下操作: var match = new RegEx(likeExpr.replace("%", ".*").replace("_", ".")).exec(str) != null; …因为模式可能包含点、星和任何其他特殊的正则表达式字符。如果要使用正则表达式,可以将字符串的每个字符都用方括号括起来。那么您只

如何在JavaScript中模拟SQL关键字

对于那些不知道什么是
的人来说,这是一个非常简单的正则表达式,它只支持通配符
%
,匹配0个或多个字符,以及只匹配一个字符

但是,不可能只执行以下操作:

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

…因为模式可能包含点、星和任何其他特殊的正则表达式字符。

如果要使用正则表达式,可以将字符串的每个字符都用方括号括起来。那么您只有几个字符可以转义


但是一个更好的选择可能是截断目标字符串,使其长度与搜索字符串匹配,并检查是否相等。

只要您首先转义模式中的正则表达式字符,您所拥有的将起作用。下面是一个例子:

然后,您可以将代码实现为:

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

以下是我使用的函数,基于:


我一直在寻找同一个问题的答案,在阅读Kip的回复后,我得出了以下结论:

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

注2013年11月29日:根据下面的Lucios评论更新了
RegExp.test()
性能改进。

在Chris Van Opstal的回答中,您应该使用replaceAll而不是replace来替换所有发生的“%”和“\ux”。
参考如何进行replaceAll-

Johnny最近来过这里,但这对我很有用,我将其用于spa页面,以避免某些页面在默认页面之后显示结果:

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 str=haystack.toLowerCase();
var n=-1;
对于(变量i=0;i-1){
返回n;
}
}
返回n;
}
用法是-此处我不想在工具、联系人或主页上显示任何结果-results()是我在此处不显示的函数:

var n = like($data,'tools,contact,home');
//~ alert(n);
if(n < 0){// does not match anything in the above string
  results($data);
}
var n=like($data,'tools,contact,home');
//~alert(n);
如果(n<0){//与上述字符串中的任何内容都不匹配
结果(数据);
}

一个老问题,但实际上这里没有好的答案。类TSQL表达式可以包含方括号转义部分,这些转义部分已经几乎是有效的正则表达式,并允许匹配
%
。例如:

'75%' LIKE '75[%]'
'[foo]' LIKE '[[]foo]' -- ugh
下面是我将LIKE表达式转换为RegExp的函数。输入分为方括号和非方括号部分。方括号部分只需要反斜杠转义,非方括号部分完全转义,而
%
\
指令转换为正则表达式

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

我想要的东西也能处理转义通配符
%
\
使用
\%
\
的问题

以下是我使用反向查找的解决方案:

//转义RegExp特殊字符
const escapePattern=s=>s.replace(/[-/\\^$*+.()[\]{}]/g,\\$&');
//将ILIKE模式转换为RegExp对象
常量ilikeToRegExp=模式=>
新正则表达式(
`^${escapePattern(模式)}$`
//转换我喜欢的通配符,不匹配转义
.替换(/(?)?
用法:

ilikeToRegExp(“%eLlo WoR%”)。测试('hello world')
//真的
ilikeToRegExp('ello wor')。test('hello world'))
//假的
ilikeToRegExp(“%90\%%”)。测试(“…90%…”)
//真的

我需要这个,在Safari中逃跑和工作(没有负面表情)。以下是我的想法:

/**
 * Quotes a string following the same rules as https://www.php.net/manual/function.preg-quote.php
 *
 * Sourced from https://locutus.io/php/preg_quote/
 *
 * @param {string} str String to quote.
 * @param {?string} [delimiter] Delimiter to also quote.
 * @returns {string} The quoted string.
 */
function regexQuote(str, delimiter) {
    return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
}

/**
 * Removes the diacritical marks from a string.
 *
 * Diacritical marks: {@link https://unicode-table.com/blocks/combining-diacritical-marks/}
 *
 * @param {string} str The string from which to strip the diacritical marks.
 * @returns {string} Stripped string.
 */
function stripDiacriticalMarks(str) {
    return unorm.nfkd(str).replaceAll(/[\u0300-\u036f]+/g, '');
}

/**
 * Checks if the string `haystack` is like `needle`, `needle` can contain '%' and '_'
 * characters which will behave as if used in a SQL LIKE condition. Character escaping
 * is supported with '\'.
 *
 * @param {string} haystack The string to check if it is like `needle`.
 * @param {string} needle The string used to check if `haystack` is like it.
 * @param {boolean} [ai] Whether to check likeness in an accent-insensitive manner.
 * @param {boolean} [ci] Whether to check likeness in a case-insensitive manner.
 * @returns {boolean} True if `haystack` is like `needle`, otherwise, false.
 */
function strLike(haystack, needle, ai = true, ci = true) {
    if (ai) {
        haystack = stripDiacriticalMarks(haystack);
        needle = stripDiacriticalMarks(needle);
    }

    needle = regexQuote(needle, '/');

    let tokens = [];

    for (let i = 0; i < needle.length; ) {
        if (needle[i] === '\\') {
            i += 2;
            if (i < needle.length) {
                if (needle[i] === '\\') {
                    tokens.push('\\\\');
                    i += 2;
                } else {
                    tokens.push(needle[i]);
                    ++i;
                }
            } else {
                tokens.push('\\\\');
            }
        } else {
            switch (needle[i]) {
                case '_':
                    tokens.push('.')
                    break;
                case '%':
                    tokens.push('.*')
                    break;
                default:
                    tokens.push(needle[i]);
                    break;
            }
            ++i;
        }
    }

    return new RegExp(`^${tokens.join('')}$`, `u${ci ? 'i' : ''}`).test(haystack);
}

/**
 * Escapes a string in a way that `strLike` will match it as-is, thus '%' and '_'
 * would match a literal '%' and '_' respectively (and not behave as in a SQL LIKE
 * condition).
 *
 * @param {string} str The string to escape.
 * @returns {string} The escaped string.
 */
function escapeStrLike(str) {
    let tokens = [];

    for (let i = 0; i < str.length; i++) {
        switch (str[i]) {
            case '\\':
                tokens.push('\\\\');
                break;
            case '%':
                tokens.push('\\%')
                break;
            case '_':
                tokens.push('\\_')
                break;
            default:
                tokens.push(str[i]);
        }
    }

    return tokens.join('');
}
/**
*按与相同的规则引用字符串https://www.php.net/manual/function.preg-quote.php
*
*来源于https://locutus.io/php/preg_quote/
*
*@param{string}str要引用的字符串。
*@param{?string}[delimiter]分隔符也要引用。
*@返回带引号的字符串{string}。
*/
函数regexQuote(str,分隔符){
返回(str+'').replace(新的RegExp('[.\\\\+*?\[\\\\^\\]$(){}=!\\;:\\'+(分隔符\\\\''+'-]','g'),'\$&');
}
/**
*从字符串中删除变音符号。
*
*变音符号:{@linkhttps://unicode-table.com/blocks/combining-diacritical-marks/}
*
*@param{string}str用于去除变音符号的字符串。
*@返回{string}条带字符串。
*/
功能条带区分标记(str){
返回unorm.nfkd(str.replaceAll(/[\u0300-\u036f]+/g');
}
/**
*检查字符串'haystack'是否类似于'needle','needle'可以包含“%”和“\u1”
*行为类似于在类似SQL的条件下使用的字符。字符转义
*由“\”支持。
*
*@param{string}干草堆叠字符串以检查它是否像“针”。
*@param{string}用于检查haystack是否与之类似的字符串。
*@param{boolean}[ai]是否以不区分重音的方式检查相似性。
*@param{boolean}[ci]是否以不区分大小写的方式检查相似性。
*@如果'haystack'类似于'needle',则返回{boolean}True,否则返回false。
*/
函数strLike(草堆、针、ai=true、ci=true){
如果(ai){
干草堆=条带临界标线(干草堆);
针=条纹色标(针);
}
针=regexQuote(针“/”);
让令牌=[];
对于(设i=0;ivar n = like($data,'tools,contact,home');
//~ alert(n);
if(n < 0){// does not match anything in the above string
  results($data);
}
'75%' LIKE '75[%]'
'[foo]' LIKE '[[]foo]' -- ugh
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');
/**
 * Quotes a string following the same rules as https://www.php.net/manual/function.preg-quote.php
 *
 * Sourced from https://locutus.io/php/preg_quote/
 *
 * @param {string} str String to quote.
 * @param {?string} [delimiter] Delimiter to also quote.
 * @returns {string} The quoted string.
 */
function regexQuote(str, delimiter) {
    return (str + '').replace(new RegExp('[.\\\\+*?\\[\\^\\]$(){}=!<>|:\\' + (delimiter || '') + '-]', 'g'), '\\$&');
}

/**
 * Removes the diacritical marks from a string.
 *
 * Diacritical marks: {@link https://unicode-table.com/blocks/combining-diacritical-marks/}
 *
 * @param {string} str The string from which to strip the diacritical marks.
 * @returns {string} Stripped string.
 */
function stripDiacriticalMarks(str) {
    return unorm.nfkd(str).replaceAll(/[\u0300-\u036f]+/g, '');
}

/**
 * Checks if the string `haystack` is like `needle`, `needle` can contain '%' and '_'
 * characters which will behave as if used in a SQL LIKE condition. Character escaping
 * is supported with '\'.
 *
 * @param {string} haystack The string to check if it is like `needle`.
 * @param {string} needle The string used to check if `haystack` is like it.
 * @param {boolean} [ai] Whether to check likeness in an accent-insensitive manner.
 * @param {boolean} [ci] Whether to check likeness in a case-insensitive manner.
 * @returns {boolean} True if `haystack` is like `needle`, otherwise, false.
 */
function strLike(haystack, needle, ai = true, ci = true) {
    if (ai) {
        haystack = stripDiacriticalMarks(haystack);
        needle = stripDiacriticalMarks(needle);
    }

    needle = regexQuote(needle, '/');

    let tokens = [];

    for (let i = 0; i < needle.length; ) {
        if (needle[i] === '\\') {
            i += 2;
            if (i < needle.length) {
                if (needle[i] === '\\') {
                    tokens.push('\\\\');
                    i += 2;
                } else {
                    tokens.push(needle[i]);
                    ++i;
                }
            } else {
                tokens.push('\\\\');
            }
        } else {
            switch (needle[i]) {
                case '_':
                    tokens.push('.')
                    break;
                case '%':
                    tokens.push('.*')
                    break;
                default:
                    tokens.push(needle[i]);
                    break;
            }
            ++i;
        }
    }

    return new RegExp(`^${tokens.join('')}$`, `u${ci ? 'i' : ''}`).test(haystack);
}

/**
 * Escapes a string in a way that `strLike` will match it as-is, thus '%' and '_'
 * would match a literal '%' and '_' respectively (and not behave as in a SQL LIKE
 * condition).
 *
 * @param {string} str The string to escape.
 * @returns {string} The escaped string.
 */
function escapeStrLike(str) {
    let tokens = [];

    for (let i = 0; i < str.length; i++) {
        switch (str[i]) {
            case '\\':
                tokens.push('\\\\');
                break;
            case '%':
                tokens.push('\\%')
                break;
            case '_':
                tokens.push('\\_')
                break;
            default:
                tokens.push(str[i]);
        }
    }

    return tokens.join('');
}
strLike('Hello I ended up writing a function based on a few answers here that worked pretty well for me. I needed something that would preserve the "startswith%" and "%endswith" syntax, and returns no matches for an empty search string.

function sqlLIKE(target, likeExp) {
  let regex = likeExp
    .replaceAll(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1')
    .replaceAll("%", ".*")
    .replaceAll("_", ".");

  if (likeExp.charAt(0) !== '%' || !likeExp.includes('%')) regex = `^${regex}`;

  if (likeExp.charAt(likeExp.length - 1) !== '%' || !likeExp.includes('%')) regex = `${regex}$`;

  return new RegExp(regex).exec(target) !== null;
}