在PHP中模拟LIKE [英] Simulating LIKE in PHP
问题描述
有没有一种方法可以用相同的语法在PHP中模拟SQL的LIKE运算符? (%
和_
通配符以及通用$escape
转义符)?
这样具有:
Is there a way to simulate the LIKE operator of SQL in PHP with the same syntax? (%
and _
wildcards and a generic $escape
escape character)?
So that having:
$value LIKE $string ESCAPE $escape
您可以使用不返回数据库就可以返回PHP评估的函数吗?
(考虑已设置$value
,$string
和$escape
值).
you can have a function that returns the PHP evaluation of that without using the database?
(consider that the $value
, $string
and $escape
values are already set).
推荐答案
好吧,经过很多娱乐和游戏,这是我想出的:
OK, after much fun and games here's what I have come up with:
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的主要区别在于,我的将输入表达式解析"为标记以生成正则表达式,而不是就地将其转换为正则表达式.
I can't break it, maybe you can find something that will. The main way in which mine differs from @nickb's is that mine "parses"(ish) the input expression into tokens to generate a regex, rather than converting it to a regex in situ.
该函数的前三个参数应该很容易解释. 第四项允许您传递 PCRE修饰符以影响用于比赛的最终正则表达式.我输入此代码的主要原因是允许您通过 在下面的评论中已删除 i
,因此它不区分大小写-我想不出任何其他可以安全使用的修饰符,但事实并非如此.
The first 3 arguments to the function should be fairly self explanatory. The fourth allows you to pass PCRE modifiers to affect the final regex used for the match. The main reason I put this in is to allow you to pass Removed per comments belowi
so it is case insensitive - I can't think of any other modifiers that will be safe to use but that may not be the case.
函数仅返回一个布尔值,指示$input
文本是否与$pattern
匹配.
Function simply returns a boolean indicating whether the $input
text matched the $pattern
or not.
EDIT ,糟糕,现已修复. 新的键盘
EDIT Oops, was broken, now fixed. New codepad
编辑,删除了第四个参数,并根据下面的注释使所有匹配项均不区分大小写
EDIT Removed fourth argument and made all matches case-insensitive per comments below
编辑:一些小的修复/改进:
EDIT A couple of small fixes/improvements:
- 将字符串断言的开始/结尾添加到生成的正则表达式中
- 添加了对最后一个令牌的跟踪,以避免在生成的正则表达式中出现多个
.*?
序列
这篇关于在PHP中模拟LIKE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!