小编典典

在PHP中模拟LIKE

sql

有没有一种方法可以用相同的语法在PHP中模拟SQL的LIKE运算符?(%以及_通配符和通用$escape转义字符)?这样具有:

$value LIKE $string ESCAPE $escape

您可以使用一个无需使用数据库就可以返回PHP评估的函数?(考虑$value$string$escape值已设置)。


阅读 263

收藏
2021-03-23

共1个答案

小编典典

好吧,经过很多的娱乐和游戏,这是我想出的:

function preg_sql_like ($input, $pattern, $escape = '\\') {

    // Split the pattern into special sequences and the rest
    $expr = '/((?:'.preg_quote($escape, '/').')?(?:'.preg_quote($escape, '/').'|%|_))/';
    $parts = preg_split($expr, $pattern, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

    // Loop the split parts and convert/escape as necessary to build regex
    $expr = '/^';
    $lastWasPercent = FALSE;
    foreach ($parts as $part) {
        switch ($part) {
            case $escape.$escape:
                $expr .= preg_quote($escape, '/');
                break;
            case $escape.'%':
                $expr .= '%';
                break;
            case $escape.'_':
                $expr .= '_';
                break;
            case '%':
                if (!$lastWasPercent) {
                    $expr .= '.*?';
                }
                break;
            case '_':
                $expr .= '.';
                break;
            default:
                $expr .= preg_quote($part, '/');
                break;
        }
        $lastWasPercent = $part == '%';
    }
    $expr .= '$/i';

    // Look for a match and return bool
    return (bool) preg_match($expr, $input);

}

我无法打破它,也许您会找到可以的东西。我的不同于@nickb的主要方法是,我的将输入表达式“解析”(ish)成令牌以生成正则表达式,而不是就地将其转换为正则表达式。

该函数的前三个参数应该很容易解释。 第四个允许您传递
PCRE修饰符
以影响用于匹配的最终正则表达式。我输入此内容的主要原因是允许您通过i它,因此它不区分大小写-
我想不出任何其他可以安全使用的修饰符,但事实并非如此。
从下面的评论中删除

函数仅返回一个布尔值,指示$input文本是否匹配$pattern

这是它的键盘

编辑 糟糕,已损坏,现在已修复。新键盘

编辑 删除第四个参数,并根据下面的注释使所有匹配项均不区分大小写

编辑 一些小修正/改进:

  • 在生成的正则表达式中添加了字符串断言的开始/结束
  • 添加了对最后一个令牌的跟踪,以避免.*?生成的正则表达式中出现多个序列
2021-03-23