正则表达式语法
通过 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 字符类。请参见正则表达式:特殊子字符类。
REGEXP '.*abc'
匹配的字符串以 abc 结尾并以任何前缀开头。因此,aabc、xyzabc 和 abc 匹配,但 bc 和 abcc 则不匹配。'colou?r'
匹配 color 和 colour。'bre+'
匹配 bre 和 bree,但不匹配 br。REGEXP '[a-e]'
匹配 a、b、c、d 和 e。
有关 REGEXP 和 SIMILAR TO 如何对范围求值的详细信息,请参见LIKE、REGEXP 和 SIMILAR TO:字符比较上的差异。
不将百分号视为 REGEXP 和 REGEXP_SUBSTR 所使用的元字符。当指定时,它匹配百分号 (%)。
不将下划线视为 REGEXP 和 REGEXP_SUBSTR 所使用的元字符。当指定时,它匹配下划线 (_)。
(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)个字符的字符串。
'^[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。
SIMILAR TO 'cat$'
匹配 cat,但不匹配 catfish。
当与 SIMILAR TO 一起使用时,它匹配问号。
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:]]
匹配除字母字符以外的所有字符的集合。
'[0-9]{3}[[:alpha:]]{2}'
匹配三个数字,后跟两个字母。'[[:alnum:]]+'
匹配含有一个或多个字母和数字的字符串。'[[:digit:]-]+'
匹配含有一个或多个数字或横线的字符串。同样,'[^[:digit:]-]+'
匹配含有一个或多个不是数字或横线的字符的字符串。'[[:lower:]]'
不匹配 A,因为 A 为大写。SELECT City FROM Contacts WHERE City REGEXP '.*[[:space:]].*';
'[[:upper:]ab]'
与以下其中一项匹配:任何大写字母、a 或 b。[[:blank:]]
等效于 [ \t]
。
[[:graph:]]
等效于 [[:alnum:][:punct:]]
。
[[:print:]]
等效于 [[:graph:][:whitespace:]]
。
[:punct:]
子字符类不能包括当前归类中可用的非 ASCII 标点字符。
[[:word:]]
等效于 [[:alnum:]_]
。
正则表达式:所支持的其它语法约定
REGEXP 搜索条件和 REGEXP_SUBSTR 函数支持以下语法约定,同时它们假定反斜线为转义字符。而 SIMILAR TO 搜索表达式不支持这些约定。
\0134
匹配反斜线。等效于在字符集外部使用的 ^
。
SELECT Surname, Surname, City, Phone FROM Contacts WHERE Phone REGEXP '\\d{8}00';
\d 既可用在字符类的内部也可用在字符类的外部,等效于 [[:digit:]]
。
\D 既可用在字符类的内部也可用在字符类的外部,等效于 [^[:digit:]]
。
在方括号内使用取非速记时请务必谨慎。[\D\S]
与 [^\d\s]
并不相同。后者匹配数字或空格以外的任何字符。所以它匹配 x,但不匹配 8。而前者匹配不是数字或不是空格(满足两个条件之一)的任何字符。因为数字不是空格,空格也不是数字,所以 [\D\S]
可以匹配任何字符、数字、空格或其它字符。
有关正则表达式元字符的列表,请参见正则表达式:元字符。
\Q[$\E
等效于 \[\$
。
有关正则表达式元字符的列表,请参见正则表达式:元字符。
SELECT Name FROM Products WHERE Name REGEXP '.*\\s.*'
\s 既可用在字符类的内部也可用在字符类的外部,等效于 [[:whitespace:]]
。请参见正则表达式:特殊子字符类。
[^[:whitespace:]]
。
\S 既可用在字符类的内部也可用在字符类的外部。请参见正则表达式:特殊子字符类。
在方括号内使用取非速记时请务必谨慎。[\D\S]
与 [^\d\s]
并不相同。后者匹配数字或空格以外的任何字符。所以它匹配 x,但不匹配 8。而前者匹配不是数字或不是空格(满足两个条件之一)的任何字符。因为数字不是空格,空格也不是数字,所以 [\D\S]
可以匹配任何字符、数字、空格或其它字符。
SELECT Surname FROM Contacts WHERE Surname REGEXP '\\w{7}';
\w 既可用在字符类的内部也可用在字符类的外部。请参见正则表达式:特殊子字符类。
等效于 [[:alnum:]_].
。
[^[:alnum:]_]
。
在字符类的内部和外部都可使用此正则表达式。请参见正则表达式:特殊子字符类。
\x2D
等效于一个连字符。
等效于 \x{hh}。
等效于 $
。
正则表达式:断言
断言测试条件是否为真,并影响字符串中开始匹配的位置。断言不返回字符;最终匹配中不包括断言模式。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 支持的断言:
'A(?=B)'
匹配后面跟有 B 的 A,但不使 B 成为匹配的一部分。
例如,SELECT REGEXP_SUBSTR( 'in new york city', 'new(?=\\syork)');
会返回子串 new,因为它后面紧跟着 ' york'(请注意 york 前面的空格)。
'A(?!B)'
匹配后面未跟着 B 的 A。
例如,SELECT REGEXP_SUBSTR('new jersey', 'new(?!\\syork)');
会返回子串 new。
'(?<=A)B'
匹配前面紧挨着 A 的 B,但不使 A 成为匹配的一部分。
例如,SELECT REGEXP_SUBSTR('new york', '(?<=new\\s)york');
会返回子串 york。
例如,SELECT REGEXP_SUBSTR('about york', '(?<!new\\s)york');
会返回子串 york。
例如,在 'aa' REGEXP '(?>a*)a'
中,(?>a*)
匹配(并消耗)aa,而决不仅仅是前导 a。因此,'aa' REGEXP '(?>a*)a'
的计算结果为 false。
例如,在 'bb' REGEXP '(?:b*)b'
中,(?:b*)
匹配(并消耗)bb。但是,与所属关系局部子表达式不同,bb 中的最后一个 b 会被放弃,以允许整个匹配成功(即,允许与在非捕获块的外部找到的 b 匹配)。
同样,'a(?:bc|b)c'
匹配 abcc 和 abc。在匹配 abc 时,bc 中最后面的 c 会发生回溯,以便可以使用组外的 c 来使匹配成功。
正则表达式示例
下表显示正则表达式的使用示例。所有示例都适用于 REGEXP,部分示例也适用于 SIMILAR TO(如[示例]列中注释)。结果视您用于搜索的搜索条件而异。对于使用 SIMILAR TO 的示例,结果还要另外根据是否区分大小写和重音而异。
有关 REGEXP 和 SIMILAR TO 如何处理匹配和计算范围的比较,请参见LIKE、REGEXP 和 SIMILAR TO 搜索条件。
请注意,如果在文字字符串中使用这些示例(例如,'.+@.+\\..+'
),则应使用双反斜线
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):
3124 5675 4400 4567, 4123-6453-2222-1746
同样,MasterCard 匹配一组 16 位的号码,以 5 开头,每四位号码组成的子集之间各有一个空格。American Express 和 Discover 是相同的,但是必须分别以 37 和 6011 开头。
([0-2][0-9]|30|31)/(0[1-9]|1[0-2])/[0-9]{4}
非匹配: 31/4/1999, 31/4/99, 1999/04/19, 42/67/25456
([A-Za-z]:|\\)\\[[:alnum:][:whitespace:]!"#$%&'()+,-.\\;=@\[\]^_`{}~.]*
非匹配:\directory\directory2, /directory2
[[:word:]\-.]+@[[:word:]\-.]+\.[[:alpha:]]{2,3}
非匹配:abc@dummy, ab*cd@efg.hijkl
.+@.+\..+
非匹配:abc.123.*&ca, ^%abcdefg123
[A-F0-9]{6}
非匹配:123G45, 12-44-CC
[A-F0-9]{2}\s[A-F0-9]{2}\s[A-F0-9]{2}
非匹配:SS AB CD, AA BB CC DD, 1223AB
((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])
非匹配: 0.0.0, 256.89.457.02
/\*.*\*/|//[^\n]*
非匹配:a=1
(\+|-)?\$[0-9]*\.[0-9]{2}
非匹配: $1, 1.00$, $-75.17
(\+|-)?[0-9]+(\.[0-9]+)?
非匹配: ++41, 41.1.19, -+97.14
[[:alnum:]]{4,10}
非匹配:abc, *ab12, abcdefghijkl
[a-zA-Z]\w{3,7}
非匹配:*&^g, abc, 1bcd
([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})
非匹配: 888 6898, 5198886898, 519 883-6898
[A-Z0-9].*(\.|\?|!)
非匹配:i am fine
[[:upper:]0-9].*[.?!]
非匹配:i am fine
[0-9]{3}-[0-9]{2}-[0-9]{4}
非匹配:123 45 6789, 123456789, 1234-56-7891
(http://)?www\.[a-zA-Z0-9]+\.[a-zA-Z]{2,3}
非匹配:http://sample.com, http://www.sample.comm
到此这篇关于SQL Anywhere正则表达式语法与示例的文章就介绍到这了,更多相关SQL Anywhere正则表达式内容请搜索易盾网络以前的文章或继续浏览下面的相关文章希望大家以后多多支持易盾网络!