欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL Anywhere正则表达式语法与示例

程序员文章站 2022-04-11 18:49:53
正则表达式语法通过 similar to 和 regexp 搜索条件以及 regexp_substr 函数支持正则表达式。对于 similar to,正则表达式语法符合 ansi/iso sql 标准...

正则表达式语法

通过 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 '[a-e]' 匹配 a、b、c、d 和 e。

有关 regexp 和 similar to 如何对范围求值的详细信息,请参见like、regexp 和 similar to:字符比较上的差异

% 百分号可与 similar to 配合使用来匹配任意数目的字符。

不将百分号视为 regexp 和 regexp_substr 所使用的元字符。当指定时,它匹配百分号 (%)。

_(下划线字符) 可将下划线与 similar to 配合使用来匹配单个字符。

不将下划线视为 regexp 和 regexp_substr 所使用的元字符。当指定时,它匹配下划线 (_)。

| 管道符号用于指定匹配字符串时要使用的替代模式。在由竖线分隔的一行模式中,竖线被解释为 or,匹配过程从最左侧的模式开始,在找到第一个匹配项时停止。因此,您应按优先级的降序顺序列出模式。您可以指定任意数量的替代模式。
() 当左括号和右括号用于正则表达式的各个组合部分时,它们为元字符。例如,(ab)* 匹配零个或多个 ab 的重复项。与使用数学表达式一样,您使用组合来控制正则表达式各部分的计算顺序。
{} 当左大括号和右大括号用于指定量词时,它们为元字符。量词指定一个模式要构成某个匹配所必须重复的次数。例如:

  • {m} 匹配某个字符正好 m 次。例如,'519-[0-9]{3}-[0-9]{4}' 匹配 519 地区号中的一个电话号码(假定数据按语法中定义的方式进行格式设置)。

  • {m,} 匹配某个字符至少 m 次。例如,'[0-9]{5,}' 匹配任何含有五个或更多数字的字符串。

  • {m,n} 匹配某个字符至少 m 次,但不超过 n 次。例如,similar to '_{5,10}' 匹配任何含有 5 到 10(含 5 和 10)个字符的字符串。

\ 反斜线被用作元字符的转义字符。它也可被用于转义非元字符。
^ 对于 regexp 和 regexp_substr,当脱字符在字符类的外部时,脱字符匹配字符串的开头字符。例如,'^[hc]at' 匹配 hat 和 cat,但只在字符串的开头。

当用在字符类内部时,以下行为适用:

  • regexp 和 regexp_substr 当脱字符为字符类中的第一个字符时,它与字符集中字符以外的任何字符匹配。例如,regexp '[^abc]' 匹配 a、b 或 c 以外的任何字符。

    如果脱字符不是方括号内的第一个字符,那么它匹配脱字符。例如,regexp_substr '[a-e^c]' 匹配 a、b、c、d、e 和 ^。

  • similar to 对于 similar to,脱字符被视作减号运算符。例如,similar to '[a-e^c]' 匹配 a、b、d 和 e。

$ 当与 regexp 和 regexp_substr 一起使用时,匹配字符串的结尾字符。例如,similar to 'cat$' 匹配 cat,但不匹配 catfish。

当与 similar to 一起使用时,它匹配问号。

. 当与 regexp 和 regexp_substr 一起使用时,匹配任何单个字符。例如,regexp 'a.cd' 匹配以 a 开头并以 cd 结尾的含有四个字符的任何字符串。

当与 similar to 一起使用时,它匹配句点 (.)。

: 在字符集中使用冒号来指定子字符类。例如,'[[:alnum:]]'

正则表达式:特殊子字符类

子字符类是嵌入到较大字符类中的特殊字符类。除了自定义字符类(在其中定义要匹配的字符集,例如,[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:] 匹配当前归类中的大写和小写字母字符。例如,'[0-9]{3}[[:alpha:]]{2}' 匹配三个数字,后跟两个字母。 y
[:alnum:] 匹配当前归类中的数字、大写和小写字母字符。例如,'[[:alnum:]]+' 匹配含有一个或多个字母和数字的字符串。 y
[:digit:] 匹配当前归类中的数字。例如,'[[:digit:]-]+' 匹配含有一个或多个数字或横线的字符串。同样,'[^[:digit:]-]+' 匹配含有一个或多个不是数字或横线的字符的字符串。 y
[:lower:] 匹配当前归类中的小写字母字符。例如,'[[:lower:]]' 不匹配 a,因为 a 为大写。 y
[:space:] 匹配单个空格 (' ')。例如,以下语句搜索 contacts.city 以查找任何名称为两个词的城市:

select city 
from contacts
where city regexp '.*[[:space:]].*';
y
[:upper:] 匹配当前归类中的大写字母字符。例如,'[[:upper:]ab]' 与以下其中一项匹配:任何大写字母、a 或 b。 y
[:whitespace:] 匹配一个空白字符,例如,空格、制表符、换页符和回车符。 y
[:ascii:] 匹配任何七位的 ascii 字符(0 到 127 之间的顺序值)。
[:blank:] 匹配一个空白区或水平制表符。

[[:blank:]] 等效于 [ \t]

[:cntrl:] 匹配顺序值小于 32 或字符值为 127 的 ascii 字符(控制字符)。控制字符包括换行符、换页符、退格符,等等。
[:graph:] 匹配打印字符。

[[:graph:]] 等效于 [[:alnum:][:punct:]]

[:print:] 匹配打印字符和空格。

[[:print:]] 等效于 [[:graph:][:whitespace:]]

[:punct:] 匹配其中一个字符: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~.

[:punct:] 子字符类不能包括当前归类中可用的非 ascii 标点字符。

[:word:] 匹配当前归类中的字母、数字或下划线字符。

[[:word:]] 等效于 [[:alnum:]_]

[:xdigit:] 匹配字符类 [0-9a-fa-f] 中的字符。

正则表达式:所支持的其它语法约定

regexp 搜索条件和 regexp_substr 函数支持以下语法约定,同时它们假定反斜线为转义字符。而 similar to 搜索表达式不支持这些约定。

正则表达式语法 名称和含义
\0xxx 匹配值为 \0xxx 的字符,其中 xxx 是任何八进制数字序列,0 是零。例如,\0134 匹配反斜线。
\a 匹配报警字符。
\a 用在字符集外部以便匹配字符串的开头。

等效于在字符集外部使用的 ^

\b 匹配退格字符。
\b 匹配反斜线字符 (\)。
\cx 匹配已命名的控制字符。例如,\cz 代表 ctrl-z。
\d 匹配当前归类中的一个数字。例如,以下语句搜索 contacts.phone 以查找以 00 结尾的所有电话号码:

select surname, surname, city, phone
 from contacts
 where phone regexp '\\d{8}00';

\d 既可用在字符类的内部也可用在字符类的外部,等效于 [[:digit:]]

\d 匹配数字以外的任何字符。它的作用与 \d 正好相反。

\d 既可用在字符类的内部也可用在字符类的外部,等效于 [^[:digit:]]

在方括号内使用取非速记时请务必谨慎。[\d\s][^\d\s] 并不相同。后者匹配数字或空格以外的任何字符。所以它匹配 x,但不匹配 8。而前者匹配不是数字或不是空格(满足两个条件之一)的任何字符。因为数字不是空格,空格也不是数字,所以 [\d\s] 可以匹配任何字符、数字、空格或其它字符。

\e 匹配转义字符。
\e 将由 \q 启动的将元字符视为非元字符这一功能停止。

有关正则表达式元字符的列表,请参见。

\f 匹配换页符。
\n 匹配换行符。
\q 将所有元字符视为非元字符,直到遇到 \e。例如,\q[$\e 等效于 \[\$

有关正则表达式元字符的列表,请参见。

\r 匹配回车符。
\s 匹配一个被视为白空格的空格或字符。例如,以下语句从 products.productname 中返回名称中至少有一个空格的所有产品名:

select name 
from products
where name regexp '.*\\s.*'

\s 既可用在字符类的内部也可用在字符类的外部,等效于 [[:whitespace:]]。请参见。

\s 匹配非白空格字符。它的作用与 \d 正好相反,而等效于 [^[:whitespace:]]

\s 既可用在字符类的内部也可用在字符类的外部。请参见。

在方括号内使用取非速记时请务必谨慎。[\d\s][^\d\s] 并不相同。后者匹配数字或空格以外的任何字符。所以它匹配 x,但不匹配 8。而前者匹配不是数字或不是空格(满足两个条件之一)的任何字符。因为数字不是空格,空格也不是数字,所以 [\d\s] 可以匹配任何字符、数字、空格或其它字符。

\t 匹配水平制表符。
\v 匹配垂直制表符。
\w 匹配当前归类中的字母字符、数字或下划线。例如,以下语句从 contacts.surname 返回长度正好为七个字母数字字符的所有姓:

select surname 
from contacts 
where surname regexp '\\w{7}';

\w 既可用在字符类的内部也可用在字符类的外部。请参见。

等效于 [[:alnum:]_].

\w 匹配当前归类中字母字符、数字或下划线以外的任何字符。它的作用与 \w 正好相反,而等效于 [^[:alnum:]_]

在字符类的内部和外部都可使用此正则表达式。请参见。

\xhh 匹配值为 0xhh 的字符,其中 hh 最多为两个十六进制数字。例如,\x2d 等效于一个连字符。

等效于 \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 不会成为匹配字符串的一部分。'a(?=b)' 匹配后面跟有 b 的 a,但不使 b 成为匹配的一部分。

例如,select regexp_substr( 'in new york city', 'new(?=\\syork)'); 会返回子串 new,因为它后面紧跟着 ' york'(请注意 york 前面的空格)。

(?!pattern) 否定的 lookahead 零宽度断言 查看字符串中的当前位置是否没有 紧跟着出现 pattern,而 pattern 不会成为匹配字符串的一部分。所以,'a(?!b)' 匹配后面未跟着 b 的 a。

例如,select regexp_substr('new jersey', 'new(?!\\syork)'); 会返回子串 new。

(?<=pattern) 肯定的 lookbehind 零宽度断言 查看字符串中的当前位置是否前面紧挨着出现了 pattern,而 pattern 不会成为匹配字符串的一部分。所以,'(?<=a)b' 匹配前面紧挨着 a 的 b,但不使 a 成为匹配的一部分。

例如,select regexp_substr('new york', '(?<=new\\s)york'); 会返回子串 york。

(?<!pattern) 否定的 lookbehind 零宽度断言 查看字符串中的当前位置的前面是否没有 紧挨着出现 pattern,而 pattern 不会成为匹配字符串的一部分。

例如,select regexp_substr('about york', '(?<!new\\s)york'); 会返回子串 york。

(?>pattern) 所属关系局部子表达式 仅匹配与 pattern 匹配的剩余字符串的最大前缀。

例如,在 'aa' regexp '(?>a*)a' 中,(?>a*) 匹配(并消耗)aa,而决不仅仅是前导 a。因此,'aa' regexp '(?>a*)a' 的计算结果为 false。

(?:pattern) 非捕获块 该语法在功能上就等效于 pattern,是为实现兼容性而提供。

例如,在 'bb' regexp '(?:b*)b' 中,(?:b*) 匹配(并消耗)bb。但是,与所属关系局部子表达式不同,bb 中的最后一个 b 会被放弃,以允许整个匹配成功(即,允许与在非捕获块的外部找到的 b 匹配)。

同样,'a(?:bc|b)c' 匹配 abcc 和 abc。在匹配 abc 时,bc 中最后面的 c 会发生回溯,以便可以使用组外的 c 来使匹配成功。

(?#text) 用于注释。text 的内容会被忽略。

正则表达式示例

下表显示正则表达式的使用示例。所有示例都适用于 regexp,部分示例也适用于 similar to(如[示例]列中注释)。结果视您用于搜索的搜索条件而异。对于使用 similar to 的示例,结果还要另外根据是否区分大小写和重音而异。

有关 regexp 和 similar to 如何处理匹配和计算范围的比较,请参见like、regexp 和 similar to 搜索条件

请注意,如果在文字字符串中使用这些示例(例如,'.+@.+\\..+'),则应使用双反斜线

示例 匹配示例
信用卡号(仅限 regexp):

visa:

4[0-9]{3}\s[0-9]{4}\s[0-9]{4}\s[0-9]{4}

mastercard:

5[0-9]{3}\s[0-9]{4}\s[0-9]{4}\s[0-9]{4}

american express:

37[0-9]{2}\s[0-9]{4}\s[0-9]{4}\s[0-9]{4}

discover:

6011\s[0-9]{4}\s[0-9]{4}\s[0-9]{4}

匹配 (visa): 4123 6453 2222 1746

非匹配 (visa):

3124 5675 4400 4567, 4123-6453-2222-1746

同样,mastercard 匹配一组 16 位的号码,以 5 开头,每四位号码组成的子集之间各有一个空格。american express 和 discover 是相同的,但是必须分别以 37 和 6011 开头。

日期(regexp 和 similar to 均适用):

([0-2][0-9]|30|31)/(0[1-9]|1[0-2])/[0-9]{4}

匹配: 31/04/1999, 15/12/4567

非匹配: 31/4/1999, 31/4/99, 1999/04/19, 42/67/25456

windows 绝对路径(仅限 regexp):

([a-za-z]:|\\)\\[[:alnum:][:whitespace:]!"#$%&'()+,-.\\;=@\[\]^_`{}~.]*

匹配:\\server\share\file

非匹配:\directory\directory2, /directory2

电子邮件地址(仅限 regexp):

[[:word:]\-.]+@[[:word:]\-.]+\.[[:alpha:]]{2,3}

匹配:abc.123@def456.com, _123@abc.ca

非匹配:abc@dummy, ab*cd@efg.hijkl

电子邮件地址(仅限 regexp):

.+@.+\..+

匹配:*@qrstuv@wxyz.12345.com, __1234^%@@abc.def.ghijkl

非匹配:abc.123.*&ca, ^%abcdefg123

html 十六进制颜色代码(regexp 和 similar to 均适用):

[a-f0-9]{6}

匹配:ab1234, cccccc, 12af3b

非匹配:123g45, 12-44-cc

html 十六进制颜色代码(仅限 regexp):

[a-f0-9]{2}\s[a-f0-9]{2}\s[a-f0-9]{2}

匹配:ab 11 00, cc 12 d3

非匹配:ss ab cd, aa bb cc dd, 1223ab

ip 地址(仅限 regexp):

((2(5[0-5]|[0-4][0-9])|1([0-9][0-9])|([1-9][0-9])|[0-9])\.){3}(2(5[0-5]|[0-4][0-9])|1([0-9][0-9])|([1-9][0-9])|[0-9])

匹配: 10.25.101.216

非匹配: 0.0.0, 256.89.457.02

java 注释(仅限 regexp):

/\*.*\*/|//[^\n]*

匹配位于 /* 和 */ 之间的 java 注释,或者前缀为 // 的一行注释。

非匹配:a=1

货币(仅限 regexp):

(\+|-)?\$[0-9]*\.[0-9]{2}

匹配: $1.00, -$97.65

非匹配: $1, 1.00$, $-75.17

正数、负数和小数值(仅限 regexp):

(\+|-)?[0-9]+(\.[0-9]+)?

匹配: +41, -412, 2, 7968412, 41, +41.1, -3.141592653

非匹配: ++41, 41.1.19, -+97.14

口令(regexp 和 similar to 均适用):

[[:alnum:]]{4,10}

匹配:abcd, 1234, a1b2c3d4, 1a2b3

非匹配:abc, *ab12, abcdefghijkl

口令(仅限 regexp):

[a-za-z]\w{3,7}

匹配:ab_cd, a1_b2c3, a123_

非匹配:*&^g, abc, 1bcd

电话号码(regexp 和 similar to 均适用):

([2-9][0-9]{2}-[2-9][0-9]{2}-[0-9]{4})|([2-9][0-9]{2}\s[2-9][0-9]{2}\s[0-9]{4})

匹配: 519-883-6898, 519 888 6898

非匹配: 888 6898, 5198886898, 519 883-6898

句子(仅限 regexp):

[a-z0-9].*(\.|\?|!)

匹配:hello, how are you?

非匹配:i am fine

句子(仅限 regexp):

[[:upper:]0-9].*[.?!]

匹配:hello, how are you?

非匹配:i am fine

社保号码(regexp 和 similar to 均适用):

[0-9]{3}-[0-9]{2}-[0-9]{4}

匹配: 123-45-6789

非匹配:123 45 6789, 123456789, 1234-56-7891

url(仅限 regexp):

(http://)?www\.[a-za-z0-9]+\.[a-za-z]{2,3}

匹配:http://www.sample.com、www.sample.com

非匹配:http://sample.com, http://www.sample.comm

到此这篇关于sql anywhere正则表达式语法与示例的文章就介绍到这了,更多相关sql anywhere正则表达式内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!