MariaDB REGEXP反斜杠转义行为异常,求原因解析
要理解这些测试结果,核心是搞清楚SQL字符串字面量的转义规则和MariaDB REGEXP使用的PCRE正则引擎的转义规则这两层处理逻辑:
- SQL字符串转义:MariaDB中,
\是字符串字面量的转义字符,仅当\后跟预定义转义序列(如\n、\\、\')时才会生效;若\后跟非预定义字符,SQL解析器会直接忽略该\,保留后面的字符。 - REGEXP引擎:MariaDB 10.0及以后默认使用PCRE(Perl兼容正则),支持
\d(匹配数字0-9)等语法,正则引擎会再次处理字符串中的\转义。
先明确测试的基础:
SET @x := 'abc\\def'; SELECT @x; -- 结果为abc\def,即@x实际存储的是包含字符`\`和`d`的字符串
接下来逐个分析测试结果:
SELECT @x REGEXP '\d'; -- 1
SQL解析时,\d不是有效SQL转义序列,解析器忽略\,将正则处理为'd'。PCRE引擎匹配字符d,@x中存在该字符,因此返回1。无报错是因为SQL解析自动处理了无效转义,正则本身合法。SELECT @x REGEXP '\\d'; -- 0
SQL解析时,\\转义为单个\,正则变为'\d'。PCRE中\d匹配数字,@x中无数字,匹配失败返回0。SELECT @x REGEXP '\\\d'; -- 0
SQL解析时,\\转义为\,剩余的\d因\无效被忽略,最终正则仍为'\d',和上一测试逻辑相同,匹配数字失败返回0。SELECT @x REGEXP '\\\\d'; -- 1
SQL解析时,两个\\分别转义为\,正则变为'\\d'。PCRE中第一个\转义第二个\,使其成为普通字符\,正则最终匹配\+d的连续子串,@x中存在该子串,返回1。SELECT @x REGEXP '\\\\\d'; -- 1
SQL解析时,前两个\\转义为两个\,剩余的\d中\被忽略,正则仍为'\\d',和上一测试逻辑一致,匹配\+d成功返回1。SELECT @x REGEXP '\\\\\\\d'; -- 0
SQL解析时,四个\\转义为两个\,正则变为'\\\\d'。PCRE中解析为\+\d,即匹配\后跟数字,@x中\后面是d而非数字,匹配失败返回0。SELECT @x REGEXP '\\\\\\\\d'; -- 0
SQL解析时,四个\\转义为两个\,正则同样是'\\\\d',匹配\+数字失败,返回0。
内容的提问来源于stack exchange,提问作者giordano

