【问题标题】:How to add flags to regular expression pattern tests?如何向正则表达式模式测试添加标志?
【发布时间】:2019-04-30 02:20:01
【问题描述】:

如何在 MySQL 中为正则表达式模式测试添加标志?

对于某些 unicode 字符,该模式似乎不区分大小写,如下所示:

SELECT
  UPPER('ö') REGEXP 'Ö' TrueResult,
  'ö' REGEXP 'Ö' FalseResult
;

返回:

TrueResult  FalseResult
    1           0

鉴于:

SELECT
  UPPER('o') REGEXP 'O' TrueResult,
  'o' REGEXP 'O' FalseResult
;

返回:

TrueResult  FalseResult
    1           1

那么例如,如何写等价于:

SELECT UPPER('ö') REGEXP 'Ö';

改用正则表达式标志?

【问题讨论】:

  • 似乎这些字符被视为二进制数据,因此区分大小写。然后,你可以做的就是使用[Öö] 作为正则表达式

标签: mysql sql regex utf-8 mysql-5.7


【解决方案1】:

二进制排序规则可能会被使用:

set @letter:='Ö';

select 'ö' like binary @letter FalseResult, 
       'Ö' like binary @letter TrueResult;

FalseResult TrueResult
----------- ----------
    0           1

【讨论】:

    【解决方案2】:

    REGEXP (RLIKE),在 MySQL 8.0 / MariaDB 10.0 之前不处理 UTF-8 字符。它愚蠢地将Ö 视为两个字节(十六进制)C396

    带有重音(等)字母的正则表达式有时会起作用,但这更多的是巧合。不要相信它。

    使用VARCHARTEXT 数据类型,以及=LIKE 等和COLLATION,您通常可以得到所需的数据。

    如果包含Ö 的列是CHARACTER SET utf8(或utf8mb4),大多数 COLLATIONs 不是utf8_bin,则“带分音符号的大写字母O”Ö 将至少比较所有这些:

    O=o=º=Ò=Õ=ò=õ=Ō=ō=Ŏ=ŏ
    

    对于utf8_hungarian_ci,和utf8_turkish_ciÖ=ö,但它们被视为不同的字母,排序在O之后和P之前。

    对于 utf8_danish_ci、utf8_icelandic_ci 和 utf8_swedish_ci Ö=ö,但它们被视为不同的字母,位于 Z 之后。

    另见collation details

    在几乎所有情况下,应该避免使用UPPER()LOWER(),而不是让“整理”来完成这项工作。

    另一个注意事项:任何以_ci 结尾的排序规则名称都表示“不区分大小写”和“不区分重音”。

    至于问题“如何写相当于:SELECT UPPER('ö') REGEXP 'Ö';,我说:

    mysql> SET NAMES utf8;
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> SELECT 'ö' = 'Ö';
    +-------------+
    | 'ö' = 'Ö'   |
    +-------------+
    |           1 |
    +-------------+
    1 row in set (0.00 sec)
    

    SET NAMES 只是为了指出我正在使用CHARACTER SET utf8 及其默认COLLATION,恰好是utf8_general_ci

    【讨论】:

      猜你喜欢
      • 2018-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-10
      • 1970-01-01
      • 2012-02-12
      相关资源
      最近更新 更多