REGEXP、LIKE 和 SIMILAR TO 搜索条件都是试图将某个模式与字符串进行匹配,在这一方面它们是类似的。而且,这三者都试图匹配整个字符串,而不是字符串内的子串。
所有这三个搜索条件的基本语法类似:
expression search-condition pattern
REGEXP、LIKE 和 SIMILAR TO 搜索条件的不同之处在于如何定义 pattern:
REGEXP 支持基于 SIMILAR TO 所支持正则表达式语法的超集。此外,为与其它产品兼容,REGEXP 搜索条件还支持几个语法扩展。另外,REGEXP 和 SIMILAR TO 还具有不同的缺省转义字符。REGEXP 的行为与 Perl 5 比较接近(除了不支持 Perl 语法和运算符的方面)。
pattern 的 LIKE 语法很简单,它支持一小组通配符,但不支持完整的正则表达式语法。
pattern 的 SIMILAR TO 语法可使用 ANSI/ISO SQL 标准中定义的正则表达式语法进行可靠的模式匹配。
在执行比较时,REGEXP 的行为不同于 LIKE 和 SIMILAR TO。对于 REGEXP 的比较,数据库服务器使用数据库字符集中的代码点值进行比较。这与 Perl 等其它正则表达式的实现方法一致。
对于 LIKE 和 SIMILAR TO,数据库服务器使用数据库归类中的等同性和排序顺序进行比较。这与数据库计算 > 和 = 等比较运算符的方法一致。
字符比较方法不同意味着 REGEXP 和 LIKE/SIMILAR 的匹配及范围计算的结果也不同。
匹配上的差异 因为 REGEXP 使用代码点值,所以只有它是完全相同的字符时才匹配模式中的文字。因此,REGEXP 匹配不受数据库归类区分大小写或区分重音等因素的影响。例如,"A" 决不会作为 "a" 的匹配项返回。
因为 LIKE 和 SIMILAR TO 使用数据库归类,在确定字符的等同性时结果会受区分大小写和区分重音的影响。例如,如果数据库归类不区分大小写和重音,则匹配项也不区分大小写和重音。因此,"A" 会作为 "a" 匹配项返回。
范围计算上的差异 因为 REGEXP 使用代码点值进行范围计算,所以,如果字符的代码点值等于范围起点和终点的代码点值,或介于这两个值之间,则认为字符在此范围之内。例如,对单个字符 x 的比较关系 x REGEXP '[A-C]'
等同于 CAST(x AS BINARY) >= CAST(A AS BINARY) AND CAST(x AS BINARY) <= CAST(C AS BINARY)
。
因为 LIKE 和 SIMILAR TO 使用归类排序顺序进行范围计算,所以,如果字符在归类中的位置与范围的起点字符和终点字符的位置相同,或在这两个位置之间,则认为字符在此范围内。例如,比较关系 x SIMILAR TO '[A-C]'
(这里 x 为单字符)等同于 x >= A AND x <= C
,并使用归类排序顺序计算比较运算符。
下表显示了在 LIKE、SIMILAR TO 和 REGEXP 所计算的 '[A-C]'
范围中包括的字符集。两个数据库都使用 1252LATIN1 归类,但第一个数据库不区分大小写,而第二个数据库区分大小写。
LIKE/SIMILAR TO '[A-C]' | REGEXP '[A-C]' | |
---|---|---|
demo.db(不区分大小写) | A、B、C、a、b、c、ª、À、Á、Â、Ã、Ä、Å、Æ、Ç、à、á、â、ã、ä、å、æ、ç | A、B、C |
charsensitive.db(区分大小写) | A、B、C、b、c、À、Á、Â、Ã、Ä、Å、Æ、Ç、ç | A、B、C |
在结果中可以观察到以下几点:
LIKE 和 SIMILAR TO 在范围中包含重音字符。
根据数据库是否区分大小写,LIKE 和 SIMILAR TO 包含不同的字符。具体地说,它们包含在范围内找到的任何小写字母,您在区分大小写的数据库中搜索时可能还没有预见到这些字母。
同样,在不区分大小写的数据库中,您假定会包含在范围中的一些字符却没有被包含进去。例如,对不区分大小写数据库执行的 SIMILAR TO '[a-c]'
包含 a、A、b、B、c,但没有包含 C,因为按照排序顺序 C 出现在小写 c 之后。
REGEXP 只返回 A、B、C,不管数据库是否区分大小写。如果想要范围内包含小写字符,必须将它们添加到范围定义中。例如,REGEXP '[a-cA-C]'
。
REGEXP 的字符集不会更改,不管数据库是否区分大小写。
尽管与上述示例相比,您的数据库使用不同的归类,或者具有不同的大小写区分或重音区分设置,但您可以通过连接到数据库并执行 LIKE、SIMILAR TO 或 REGEXP 这些语句中的任一句来执行类似的测试,以查看这些语句会返回什么结果:
SELECT CHAR( row_num ) FROM RowGenerator WHERE CHAR( row_num ) LIKE '[A-C]'; SELECT CHAR( row_num ) FROM RowGenerator WHERE CHAR( row_num ) REGEXP '[A-C]'; SELECT CHAR( row_num ) FROM RowGenerator WHERE CHAR( row_num ) SIMILAR TO '[A-C]'; |
LIKE 搜索条件
REGEXP 搜索条件
SIMILAR TO 搜索条件
Copyright © 2009, iAnywhere Solutions, Inc. - SQL Anywhere 11.0.1 |