在PHP中模拟LIKE

Sho*_*hoe 7 php sql string pcre sql-like

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

$value LIKE $string ESCAPE $escape
Run Code Online (Sandbox Code Playgroud)

你可以有一个函数,在不使用数据库的情况下返回PHP的评估吗?(考虑到$value,$string并且$escape已经设置了值).

Dav*_*dom 5

好吧,经过很多乐趣和游戏之后,我得出的结论是:

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

}
Run Code Online (Sandbox Code Playgroud)

我无法打破它,也许你能找到能打破它的东西。我的与 @nickb 的主要不同之处在于,我的将输入表达式“解析”(ish)为标记以生成正则表达式,而不是就地将其转换为正则表达式。

该函数的前 3 个参数应该是相当不言自明的。第四个允许您传递PCRE 修饰符来影响用于匹配的最终正则表达式。我将其放入的主要原因是允许您通过i,因此它不区分大小写 - 我想不出任何其他可以安全使用的修饰符,但情况可能并非如此。 根据下面的评论删除

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

这是它的键盘

编辑哎呀,被破坏了,现在修复了。新键盘

编辑删除了第四个参数并使所有匹配项不区分大小写(根据下面的评论)

编辑一些小修复/改进:

  • 添加了字符串断言的开始/结束到生成的正则表达式
  • 添加了对最后一个标记的跟踪,以避免.*?生成的正则表达式中存在多个序列