在SQLite中,我想區分大小寫"SELECT LIKE name"
對正常的拉丁名稱可以正常工作,但是當名稱使用非拉丁字符的UTF-8時,select將區分大小寫,如何使其生效也像拉丁字符一樣不區分大小寫?不區分大小寫utf8 select
p.s.我的SQLite是v3和我用PHP PDO
在SQLite中,我想區分大小寫"SELECT LIKE name"
對正常的拉丁名稱可以正常工作,但是當名稱使用非拉丁字符的UTF-8時,select將區分大小寫,如何使其生效也像拉丁字符一樣不區分大小寫?不區分大小寫utf8 select
p.s.我的SQLite是v3和我用PHP PDO
SQLite的你有2種選擇:
$pdo = new PDO("sqlite::memory:");
# BEGIN
function lexa_ci_utf8_like($mask, $value) {
$mask = str_replace(
array("%", "_"),
array(".*?", "."),
preg_quote($mask, "/")
);
$mask = "/^$mask$/ui";
return preg_match($mask, $value);
}
$pdo->sqliteCreateFunction('like', "lexa_ci_utf8_like", 2);
# END
$pdo->exec("create table t1 (x)");
$pdo->exec("insert into t1 (x) values ('[Привет España Dvořák]')");
header("Content-Type: text/plain; charset=utf8");
$q = $pdo->query("select x from t1 where x like '[_РИ%Ñ%ŘÁ_]'");
print $q->fetchColumn();
使用no-case collation連接,如:LIKE name COLLATE NOCASE
如果你需要非ASCII的部分與外殼摺疊進行比較特定的字符,該NOCASE
將無法正常工作,因爲SQLite不支持這樣的摺疊 - 您將不得不使用您選擇的Unicode庫和sqlite3_create_collation()
來提供自己的排序規則功能。
編輯:同樣,這可能是有趣:
的LIKE
的改進版本通過UDF超載:
$db->sqliteCreateFunction('like',
function ($pattern, $data, $escape = null) use ($db)
{
static $modifiers = null;
if (isset($modifiers) !== true)
{
$modifiers = ((strncmp($db->query('PRAGMA case_sensitive_like;')->fetchColumn(), '1', 1) === 0) ? '' : 'i') . 'suS';
}
if (isset($data) === true)
{
if (strpbrk($pattern = preg_quote($pattern, '~'), '%_') !== false)
{
$regex = array
(
'~%+~S' => '.*',
'~_~S' => '.',
);
if (strlen($escape = preg_quote($escape, '~')) > 0)
{
$regex = array
(
'~(?<!' . $escape . ')%+~S' => '.*',
'~(?<!' . $escape . ')_~S' => '.',
'~(?:' . preg_quote($escape, '~') . ')([%_])~S' => '$1',
);
}
$pattern = preg_replace(array_keys($regex), $regex, $pattern);
}
return (preg_match(sprintf('~^%s$~%s', $pattern, $modifiers), $data) > 0);
}
return false;
}
);
尊重case_sensitive_like
PRAGMA和正確處理x LIKE y ESCAPE z
syntax。
我還寫了另外一個版本,做basic和x
和y
值extended romanization,使重音字符將匹配它的重音對應,例如:SELECT 'Á' LIKE 'à%';
。
你可以star the gist來關注偶爾的更新。
根據NOCASE的文檔,它只是ASCII;它明確表示它不包括UTF-8。 – borrible 2010-11-26 12:56:58
文檔說的是,不屬於ASCII **的UTF-8字符**將區分大小寫。所以A = a但是Œ!=œ。編輯澄清。 – 2010-11-26 13:04:54