好吧,经过很多乐趣和游戏之后,我得出的结论是:
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)为标记以生成正则表达式,而不是就地将其转换为正则表达式。
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 i
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. Removed per comments below
函数只是返回一个布尔值,指示是否$input
文本匹配$pattern
or not.
这是它的键盘
EDIT哎呀,坏了,现在修好了。新键盘
EDIT删除了第四个参数并使所有匹配项不区分大小写(根据下面的评论)
EDIT一些小修复/改进:
- 添加了字符串断言的开始/结束到生成的正则表达式
- 添加了对最后一个令牌的跟踪以避免多次
.*?
生成的正则表达式中的序列