正则表达式语法
通过 SIMILAR TO 和 REGEXP 搜索条件以及 REGEXP_SUBSTR 函数支持正则表达式。对于 SIMILAR TO,正则表达式语法符合 ANSI/ISO SQL 标准。对于 REGEXP 和 REGEXP_SUBSTR,正则表达式的语法和支持符合 Perl 5。
REGEXP 和 SIMILAR TO 使用正则表达式是与字符串 相匹配,而 REGEXP_SUBSTR 使用正则表达式则是与子串 相匹配。要实现 REGEXP 和 SIMILAR TO 的子串匹配行为,可在要尝试匹配的模式的任何一侧指定通配符。例如,REGEXP '.*car.*'
会与 car、carwash 和 vicar 匹配。或者,可重写查询以使用 REGEXP_SUBSTR 函数。请参见REGEXP_SUBSTR 函数 [String]。
通过 SIMILAR TO 匹配的正则表达式不区分大小写,也不区分重音。REGEXP 和 REGEXP_SUBSTR 不受数据库区分重音和大小写的影响。请参见LIKE、REGEXP 和 SIMILAR TO:字符比较上的差异。
正则表达式:元字符
元字符是在正则表达式中具有特殊含义的符号或字符。
元字符的处理视以下情况而异:
-
正则表达式是与 SIMILAR TO 或 REGEXP 搜索条件一起使用,还是与 REGEXP_SUBSTR 函数一起使用
-
元字符是否在正则表达式的字符类的内部
在继续之前,应了解字符类的定义。字符类是一组括在方括号内的字符,将根据这组字符对字符串中的字符进行匹配。例如,在 SIMILAR TO 'ab[1-9]'
语法中,[1-9] 就是一个字符类,它与 1 到 9 范围中(包括 1 和 9)的某一数字匹配。正则表达式中元字符的处理方式各不相同,这取决于元字符是否被放在字符类的内部。具体来说,当元字符放在字符类的内部时,多数元字符作为常规字符来处理。
对于 SIMILAR TO(仅限于 SIMILAR TO),元字符 *、?、+、_、|、(、)、{ 必须在字符类内进行转义。
要在字符类中包括减号 (-)、脱字符 (^) 或直角方括号 (]) 字符,必须将字符转义。
下面给出了所支持的正则表达式元字符的列表。当 SIMILAR TO、REGEXP 和 REGEXP_SUBSTR 使用元字符时,几乎所有元字符的处理方式都相同:
字符 | 其它信息 |
---|---|
[ 和 ] | 左右方括号用于指定字符类。字符类是进行匹配时所要依据的一组字符。 除连字符 (-) 和脱字符 (^) 外,在字符类中指定的元字符和量词(如 * 和 {m},分别为元字符和量词)没有特殊意义,可当作实际字符进行运算。 SQL Anywhere 还支持子字符类,例如 POSIX 字符类。请参见正则表达式:特殊子字符类。 |
* | 星号可用于与字符匹配 0 次或多次。例如,REGEXP '.*abc' 匹配的字符串以 abc 结尾并以任何前缀开头。因此,aabc、xyzabc 和 abc 匹配,但 bc 和 abcc 则不匹配。 |
? | 问号可用于与字符匹配 0 次或 1 次。例如,'colou?r' 匹配 color 和 colour。 |
+ | 加号可用于与字符匹配 1 次或多次。例如,'bre+' 匹配 bre 和 bree,但不匹配 br。 |
- | 可以在字符类中使用一个连字符来表示一个范围。例如, 有关 REGEXP 和 SIMILAR TO 如何对范围求值的详细信息,请参见LIKE、REGEXP 和 SIMILAR TO:字符比较上的差异。 |
% | 百分号可与 SIMILAR TO 配合使用来匹配任意数目的字符。 不将百分号视为 REGEXP 和 REGEXP_SUBSTR 所使用的元字符。当指定时,它匹配百分号 (%)。 |
_(下划线字符) | 可将下划线与 SIMILAR TO 配合使用来匹配单个字符。 不将下划线视为 REGEXP 和 REGEXP_SUBSTR 所使用的元字符。当指定时,它匹配下划线 (_)。 |
| | 管道符号用于指定匹配字符串时要使用的替代模式。在由竖线分隔的一行模式中,竖线被解释为 OR,匹配过程从最左侧的模式开始,在找到第一个匹配项时停止。因此,您应按优先级的降序顺序列出模式。您可以指定任意数量的替代模式。 |
( 和 ) | 当左括号和右括号用于正则表达式的各个组合部分时,它们为元字符。例如,(ab)* 匹配零个或多个 ab 的重复项。与使用数学表达式一样,您使用组合来控制正则表达式各部分的计算顺序。 |
{ 和 } | 当左大括号和右大括号用于指定量词时,它们为元字符。量词指定一个模式要构成某个匹配所必须重复的次数。例如:
|
\ | 反斜线被用作元字符的转义字符。它也可被用于转义非元字符。 |
^ | 对于 REGEXP 和 REGEXP_SUBSTR,当脱字符在字符类的外部时,脱字符匹配字符串的开头字符。例如, 当用在字符类内部时,以下行为适用:
|
$ | 当与 REGEXP 和 REGEXP_SUBSTR 一起使用时,匹配字符串的结尾字符。例如, 当与 SIMILAR TO 一起使用时,它匹配问号。 |
. | 当与 REGEXP 和 REGEXP_SUBSTR 一起使用时,匹配任何单个字符。例如, 当与 SIMILAR TO 一起使用时,它匹配句点 (.)。 |
: | 在字符集中使用冒号来指定子字符类。例如, |
正则表达式:特殊子字符类
子字符类是嵌入到较大字符类中的特殊字符类。除了自定义字符类(在其中定义要匹配的字符集,例如,[abxq4]
将匹配字符集限制为 a、b、x、q 和 4)以外,SQL Anywhere 还支持子字符类,例如,大部分 POSIX 字符类。例如,[[:alpha:]]
表示所有大写和小写字母的集合。
REGEXP 搜索条件和 REGEXP_SUBSTR 函数支持下表中的所有语法约定,但 SIMILAR TO 搜索表达式不支持。SIMILAR TO 支持的约定在 SIMILAR TO 列中有一个 Y。
在 REGEXP 中,当使用 REGEXP_SUBSTR 函数时,可以使用脱字符对子字符类取非。例如,[[:^alpha:]]
匹配除字母字符以外的所有字符的集合。
子字符类 | 其它信息 | SIMILAR TO | ||
---|---|---|---|---|
[:alpha:] | 匹配当前归类中的大写和小写字母字符。例如, | Y | ||
[:alnum:] | 匹配当前归类中的数字、大写和小写字母字符。例如, | Y | ||
[:digit:] | 匹配当前归类中的数字。例如, | Y | ||
[:lower:] | 匹配当前归类中的小写字母字符。例如, | Y | ||
[:space:] | 匹配单个空格 (' ')。例如,以下语句搜索 Contacts.City 以查找任何名称为两个词的城市:
| Y | ||
[:upper:] | 匹配当前归类中的大写字母字符。例如, | Y | ||
[:whitespace:] | 匹配一个空白字符,例如,空格、制表符、换页符和回车符。 | Y | ||
[:ascii:] | 匹配任何七位的 ASCII 字符(0 到 127 之间的顺序值)。 | |||
[:blank:] | 匹配一个空白区或水平制表符。
| |||
[:cntrl:] | 匹配顺序值小于 32 或字符值为 127 的 ASCII 字符(控制字符)。控制字符包括换行符、换页符、退格符,等等。 | |||
[:graph:] | 匹配打印字符。
| |||
[:print:] | 匹配打印字符和空格。
| |||
[:punct:] | 匹配其中一个字符: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~.
| |||
[:word:] | 匹配当前归类中的字母、数字或下划线字符。
| |||
[:xdigit:] | 匹配字符类 [0-9A-Fa-f] 中的字符。 |
正则表达式:所支持的其它语法约定
REGEXP 搜索条件和 REGEXP_SUBSTR 函数支持以下语法约定,同时它们假定反斜线为转义字符。而 SIMILAR TO 搜索表达式不支持这些约定。
正则表达式语法 | 名称和含义 | ||
---|---|---|---|
\0xxx | 匹配值为 \0xxx 的字符,其中 xxx 是任何八进制数字序列,0 是零。例如, | ||
\a | 匹配报警字符。 | ||
\A | 用在字符集外部以便匹配字符串的开头。 等效于在字符集外部使用的 | ||
\b | 匹配退格字符。 | ||
\B | 匹配反斜线字符 (\)。 | ||
\cX | 匹配已命名的控制字符。例如,\cZ 代表 ctrl-Z。 | ||
\d | 匹配当前归类中的一个数字。例如,以下语句搜索 Contacts.Phone 以查找以 00 结尾的所有电话号码:
\d 既可用在字符类的内部也可用在字符类的外部,等效于 | ||
\D | 匹配数字以外的任何字符。它的作用与 \d 正好相反。 \D 既可用在字符类的内部也可用在字符类的外部,等效于 在方括号内使用取非速记时请务必谨慎。 | ||
\e | 匹配转义字符。 | ||
\E | 将由 \Q 启动的将元字符视为非元字符这一功能停止。 有关正则表达式元字符的列表 | ||
\f | 匹配换页符。 | ||
\n | 匹配换行符。 | ||
\Q | 将所有元字符视为非元字符,直到遇到 \E。例如, 有关正则表达式元字符的列表,请参见正则表达式:元字符。 | ||
\r | 匹配回车符。 | ||
\s | 匹配一个被视为白空格的空格或字符。例如,以下语句从 Products.ProductName 中返回名称中至少有一个空格的所有产品名:
\s 既可用在字符类的内部也可用在字符类的外部,等效于 | ||
\S | 匹配非白空格字符。它的作用与 \d 正好相反,而等效于 \S 既可用在字符类的内部也可用在字符类的外部。请参见正则表达式:特殊子字符类。 在方括号内使用取非速记时请务必谨慎。 | ||
\t | 匹配水平制表符。 | ||
\v | 匹配垂直制表符。 | ||
\w | 匹配当前归类中的字母字符、数字或下划线。例如,以下语句从 Contacts.Surname 返回长度正好为七个字母数字字符的所有姓:
\w 既可用在字符类的内部也可用在字符类的外部。 等效于 | ||
\W | 匹配当前归类中字母字符、数字或下划线以外的任何字符。它的作用与 \w 正好相反,而等效于 在字符类的内部和外部都可使用此正则表达式。 | ||
\xhh | 匹配值为 0xhh 的字符,其中 hh 最多为两个十六进制数字。例如, 等效于 \x{hh}。 | ||
\x{hhh} | 匹配值为 0xhhh 的字符,其中 hhh 最多为三个十六进制数字。 | ||
\z 和 \Z | 匹配字符串结尾处的位置(而非字符)。 等效于 |
正则表达式:断言
断言测试条件是否为真,并影响字符串中开始匹配的位置。断言不返回字符;最终匹配中不包括断言模式。REGEXP 搜索条件和 REGEXP_SUBSTR 函数支持这些断言模式。而 SIMILAR TO 搜索表达式不支持这些约定。
在尝试拆分字符串时,lookahead 和 lookbehind 断言对于 REGEXP_SUBSTR 将非常有用。例如,您可以通过执行以下语句返回 Customers 表的 Address 列中街道名称(不带街道编号)的列表:
SELECT REGEXP_SUBSTR( Street, '(?<=^\\S+\\s+).*$' ) FROM Customers; |
另一个示例:假定您想要使用正则表达式来验证口令是否符合某些规则。您可以使用类似于下面内容的零宽度断言:
IF password REGEXP '(?=.*[[:digit:]])(?=.*[[:alpha:]].*[[:alpha:]])[[:word:]]{4,12}' MESSAGE 'Password conforms' TO CLIENT; ELSE MESSAGE 'Password does not conform' TO CLIENT; END IF |
当满足以下条件时,口令有效:
-
password 至少有一位数(零宽度肯定断言 [[:digit:]])
-
password 至少有两个字母字符(零宽度肯定断言 [[:alpha:]].*[[:alpha:]])
-
password 只含有字母数字字符或下划线字符 ([[:word:]])
-
password 最少含有 4 个字符,最多含有 12 个字符 ({4,12})
下表包含 SQL Anywhere 支持的断言:
语法 | 含义 |
---|---|
(?=pattern) | 肯定的 lookahead 零宽度断言 查看字符串中的当前位置是否紧跟着出现了 pattern,而 pattern 不会成为匹配字符串的一部分。 例如, |
(?!pattern) | 否定的 lookahead 零宽度断言 查看字符串中的当前位置是否没有 紧跟着出现 pattern,而 pattern 不会成为匹配字符串的一部分。所以, 例如, |
(?<=pattern) | 肯定的 lookbehind 零宽度断言 查看字符串中的当前位置是否前面紧挨着出现了 pattern,而 pattern 不会成为匹配字符串的一部分。所以, 例如, |
(?<!pattern) | 否定的 lookbehind 零宽度断言 查看字符串中的当前位置的前面是否没有 紧挨着出现 pattern,而 pattern 不会成为匹配字符串的一部分。 例如, |
(?>pattern) | 所属关系局部子表达式 仅匹配与 pattern 匹配的剩余字符串的最大前缀。 例如,在 |
(?:pattern) | 非捕获块 该语法在功能上就等效于 pattern,是为实现兼容性而提供。 例如,在 同样, |
(?#text) | 用于注释。text 的内容会被忽略。 |