2

我想制作一个产品搜索引擎,用户输入产品代码并返回结果,这很容易。

但是,我希望能够补偿看起来像字母的数字,反之亦然。

例如,用户键入 6O12l,但产品代码实际上是 60121。

我需要在 SQL 查询中添加什么来恢复所有带有 6O12l 和/或 60121 的产品?


到目前为止,我有这个不起作用,无论我输入什么,它每次都会返回相同的结果:

$searchString = $_POST['query'] ;
$searchString = preg_replace('#\W#', '', $searchString);

$firstLetter = substr($searchString, 0, 1) ;

include("db.php") ;

$result = $dbh->prepare("SELECT productCode
                     FROM products
                     WHERE productCodeREGEXP '6[O0]12[1l]'
                     AND productCode LIKE '$firstLetter%'") ;
$result->execute() ;

while($row = $result->fetch(PDO::FETCH_ASSOC)) {
echo $row['productCode'].'<br />' ;
}

我设法让它工作,但我遇到了一个新问题。

我正在使用 str_replace 将字母替换为用户查询字符串中的数字,反之亦然,但它仅适用于其中一个,而不适用于两者:

$qString = str_replace(array('o', 'l', '0', '1'), array('[O0]', '[1l]', '[O0]', '[1l]'), $searchString) ;

这给了我一个错误的输出,例如 A[[1l]l]BC 而不是 A[1l]BC

4

5 回答 5

1

用这个:

SELECT * from products
where code REGEXP '6[O0]12[1l]'
于 2012-07-01T14:42:13.397 回答
1

你有带字母的产品代码吗?您可以在运行查询之前将查询字符串转换为所有数字。这是最容易做的事情,而且比测试两者都要快得多。

于 2012-07-01T14:43:02.233 回答
1

您无法使用正则表达式有效地搜索数据库。但是,您可以转换您的数据以便以规范化的形式存储,并使用规范化的查询字符串进行搜索,例如所有O' 到零,I以及l' 到一个等等。

于 2012-07-01T14:46:32.983 回答
0

我解决了:D

作为参考,我在 PHP.net 上找到了这个函数:

function search_replace($s,$r,$sql)
{ $e = '/('.implode('|',array_map('preg_quote', $s)).')/';
$r = array_combine($s,$r);
return preg_replace_callback($e, function($v) use ($s,$r) { return $r[$v[1]]; },$sql);
} 
于 2012-07-01T16:05:13.147 回答
0

另外一个选项

// regex expresssion 
// str_replace goes in order, first change letters to numbers, then change to the regex
// 6012ol becomes 6[0O][1l]2[0O][1l]
$regexString = str_replace(array('o', 'l', '0', '1'), array('0', '1', '[0O]', '[1l]'), $searchString);

// like expression, allows the database to make the initial filter, _ is the single character match
// 6012ol becomes 6__2__
$likeString = str_replace(array('o', 'l', '0', '1'), '_'), $searchString);

$filt1 = "(productCode LIKE '$likeString%')"; // last % allows for partial matches
$filt2 = "(productCode REGEXP '$regexString')";

// now query, with the like filter first
$dbh->prepare("SELECT productCode
                      FROM products
                      WHERE $filt1 AND $filt2
              ") ;
于 2014-02-16T12:31:05.130 回答