不区分大小写的 utf8 选择

发布于 2024-10-04 12:50:01 字数 167 浏览 4 评论 0原文

在 SQLite 中我想要不区分大小写 "SELECT LIKE name" 对于正常的拉丁名称工作正常,但是当名称为 UTF-8 且包含非拉丁字符时,选择将区分大小写,如何使其像拉丁字符一样不区分大小写?

ps 我的 sqlite 是 v3 并且我使用 PHP PDO 连接

In SQLite I want to case-insensitive "SELECT LIKE name"
works fine for normal latin names, but when the name is in UTF-8 with non-latin characters then the select becomes case-sensitive, how to make it also case-insensitive like latin characters?

p.s. my sqlite is v3 and I connect with PHP PDO

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

桃酥萝莉 2024-10-11 12:50:01

对于 SQLite,您有 2 个选项:

  1. 使用 ICU 支持进行编译:如何编译编译选项
  2. 覆盖LIKE函数,这里是一个完整的解决方案(来自http://blog.amartynov.ru/?p=675)
$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();

For SQLite you have 2 options:

  1. compile it with ICU support: How to compile, Compilation options
  2. override the LIKE function, here is a complete solution (from http://blog.amartynov.ru/?p=675)
$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();
朕就是辣么酷 2024-10-11 12:50:01

使用无大小写排序规则,例如:LIKE name COLLATE NOCASE< /code>

如果您需要将不属于 ASCII 的特定字符与大小写折叠进行比较,则 NOCASE 将不起作用,因为 SQLite 不支持此类折叠 - 您必须提供自己的使用您选择的 Unicode 库和 sqlite3_create_collat​​ion() 的排序函数。

编辑:另外,这可能很有趣:

如何使用指定的语言环境对 sqlite3 中的文本进行排序?

Use a no-case collation, such as : LIKE name COLLATE NOCASE

If you need specific characters that are not part of ASCII to be compared with case folding, the NOCASE will not work, as such folding is not supported by SQLite - you will have to provide your own collation function using your Unicode library of choice and sqlite3_create_collation().

EDIT: also, this might be interesting:

How to sort text in sqlite3 with specified locale?

束缚m 2024-10-11 12:50:01

通过 UDF 进行 LIKE 重载的改进版本:

$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 语法

我还编写了另一个版本基本扩展罗马化 xy 值,以便重音字符与其对应的非重音字符相匹配,例如:SELECT 'Á' LIKE 'à%';

您可以为要点加注星标以关注偶尔的更新。

An improved version of LIKE overloading via a 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;
    }
);

Respects the case_sensitive_like PRAGMA and correctly handles x LIKE y ESCAPE z syntax.

I also wrote another version that does basic and extended romanization of x and y values, so that an accented character will match it's unaccented counterpart, for instance: SELECT 'Á' LIKE 'à%';.

You can star the gist to keep an eye on occasional updates.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文