9.6. 模式匹配 #
PostgreSQL 提供了三种独立的模式匹配方法:传统的 SQL
LIKE 操作符、较新的
SQL99
SIMILAR TO 操作符,以及
POSIX 风格的正则表达式。此外还有一个模式匹配函数
substring 可用,它可以使用
SQL99 风格或 POSIX 风格的正则表达式。
提示
如果你的模式匹配的要求超出了这些,请考虑用 Perl 或 Tcl 写一个用户定义的函数。
9.6.1. LIKE #
stringLIKEpattern[ESCAPEescape-character]stringNOT LIKEpattern[ESCAPEescape-character]
每个 pattern(模式)都定义了一个字符串集合。如果 string(字符串)包含在
pattern 所表示的字符串集合中,LIKE 表达式就返回真。(与预期的一样,如果 LIKE 返回真,NOT LIKE
表达式就返回假,反之亦然。等价的表达式是
NOT (。)
string LIKE
pattern)
如果 pattern 不包含百分号或下划线,那么该模式只表示字符串本身;此时 LIKE
的行为与等于操作符相同。pattern 中的下划线(_)代表(匹配)任意单个字符;百分号(%)匹配任意零个或多个字符的字符串。
一些示例:
'abc' LIKE 'abc' true 'abc' LIKE 'a%' true 'abc' LIKE '_b_' true 'abc' LIKE 'c' false
LIKE 模式匹配总是覆盖整个字符串。要匹配字符串中任意位置的模式,模式必须以百分号开头并以百分号结尾。
要匹配字面量下划线或百分号而不是把它们当作通配符,pattern中相应的字符前面必须带有转义字符。默认的转义字符是反斜线,但也可以使用ESCAPE子句选择其他转义字符。要匹配转义字符本身,请写两个转义字符。
注意,反斜线在字符串常量中本来就有特殊含义,因此要写一个包含反斜线的模式常量,必须在 SQL 语句中写两个反斜线。这样,要写一个实际匹配字面量反斜线的模式,就意味着在语句中写四个反斜线。可以通过ESCAPE选择不同的转义字符来避免这一点;这样反斜线对LIKE就不再是特殊字符。(但反斜线对字符串常量解析器仍然是特殊字符,因此要匹配一个反斜线仍需写两个。)
也可以通过写 ESCAPE '' 来选择不使用转义字符。这会禁用转义机制,从而无法关闭模式中下划线和百分号的特殊含义。
可以使用关键字 ILIKE 代替
LIKE,按照当前的区域设置使匹配不区分大小写。这不是 SQL 标准的内容,而是
PostgreSQL 的扩展。
操作符~~等效于LIKE,而~~*对应ILIKE。还有 !~~和!~~*操作符分别代表NOT LIKE和NOT ILIKE。所有这些操作符都是PostgreSQL特有的。
9.6.2. SIMILAR TO 和 SQL99
正则表达式 #
stringSIMILAR TOpattern[ESCAPEescape-character]stringNOT SIMILAR TOpattern[ESCAPEescape-character]
SIMILAR TO 操作符根据其模式是否匹配给定字符串返回真或假。它与 LIKE 非常相似,区别在于它使用 SQL99 对正则表达式的定义来解释模式。SQL99 的正则表达式是
LIKE 记法和常用正则表达式记法的一种奇特交叉。
与LIKE类似,SIMILAR TO操作符只有在其模式匹配整个字符串时才算成功;这一点不同于普通正则表达式,后者可以匹配字符串的任意部分。与LIKE相同,SIMILAR TO也使用_和%作为通配符,分别匹配任意单个字符和任意字符串(分别类似于 POSIX 正则表达式中的.和.*)。
除了这些从LIKE借用的功能之外,SIMILAR TO支持下面这些从 POSIX 正则表达式借用的模式匹配元字符:
|表示选择(两个候选之一)。*表示重复前面的项零次或更多次。+表示重复前面的项一次或更多次。可以使用圆括号
()把多个项组合成一个逻辑项。一个方括号表达式
[...]声明一个字符类,就像 POSIX 正则表达式一样。
注意,有界重复(?和{...})没有提供,尽管它们存在于 POSIX 中。另外,点号(.)不是 SIMILAR TO 的一个元字符。
与LIKE一样,反斜杠会禁用这些元字符的特殊含义;也可以用 ESCAPE 指定其他转义字符。
下面是一些示例:
'abc' SIMILAR TO 'abc' true 'abc' SIMILAR TO 'a' false 'abc' SIMILAR TO '%(b|d)%' true 'abc' SIMILAR TO '(b|c)%' false
带三个参数的 substring 函数
substring(
提取与 SQL99
正则表达式模式匹配的子串。与 string from
pattern for
escape-character)SIMILAR TO 一样,指定的模式必须匹配整个数据字符串,否则函数失败并返回空值。要指明模式中成功时应当返回的部分,模式必须包含两处后面跟着双引号(")的转义字符。返回的文本是与这两个标记之间的模式部分匹配的文本。
下面是一些示例:
substring('foobar' from '%#"o_b#"%' for '#') oob
substring('foobar' from '#"o_b#"%' for '#') NULL
9.6.3. POSIX正则表达式 #
表 9.11列出了所有可用于 POSIX 正则表达式模式匹配的操作符。
表 9.11. 正则表达式匹配操作符
| 操作符 | 描述 | 示例 |
|---|---|---|
~ | 匹配正则表达式,区分大小写 | 'thomas' ~ '.*thomas.*' |
~* | 匹配正则表达式,不区分大小写 | 'thomas' ~* '.*Thomas.*' |
!~ | 不匹配正则表达式,区分大小写 | 'thomas' !~ '.*Thomas.*' |
!~* | 不匹配正则表达式,不区分大小写 | 'thomas' !~* '.*vadim.*' |
POSIX正则表达式提供了比LIKE和SIMILAR TO操作符更强大的模式匹配方式。许多 Unix 工具,例如egrep、sed或awk,都使用与这里描述的模式匹配语言相似的语言。
正则表达式是一个字符序列,它是一个字符串集合(正则集)的缩写定义。如果一个字符串是正则表达式所描述的正则集中的成员,就说该字符串匹配这个正则表达式。与 LIKE 一样,模式字符与字符串字符精确匹配,除非它们是正则表达式语言中的特殊字符——
但正则表达式使用的特殊字符与 LIKE 不同。与 LIKE 模式不同的是,除非正则表达式被显式地锚定到字符串的开头或结尾,否则正则表达式可以匹配字符串中任意位置的内容。
下面是一些示例:
'abc' ~ 'abc' true 'abc' ~ '^a' true 'abc' ~ '(b|d)' true 'abc' ~ '^(b|c)' false
带两个参数的 substring 函数
substring(
提取与 POSIX 正则表达式模式匹配的子串。如果没有匹配则返回空值,否则返回与模式匹配的文本部分。但是,如果模式包含任何圆括号,则返回与第一个带圆括号的子表达式(左圆括号最先出现的那个)匹配的文本部分。如果想在表达式中使用圆括号而又不触发这一例外,总可以把整个表达式用圆括号括起来。另请参阅下文描述的非捕获圆括号。
string from
pattern)
下面是一些示例:
substring('foobar' from 'o.b') oob
substring('foobar' from 'o(.)b') o
PostgreSQL的正则表达式是使用 Henry Spencer 写的一个包来实现的。下面的正则表达式的大部分描述都是从他的手册页中逐字拷贝过来的。
9.6.3.1. 正则表达式细节 #
正则表达式(RE),在POSIX 1003.2 中定义,它有两种形式:扩展的RE或者是ERE(大概地说就是那些在egrep里的),基本的RE或者是BRE(大概地说就是那些在ed里的)。PostgreSQL支持两种形式,并且还实现了一些POSIX标准中没有但是在类似 Perl 或者 Tcl 这样的语言中得到广泛应用的一些扩展。使用了那些非POSIX扩展的RE叫高级RE,或者本文档里说的ARE。ARE 几乎完全是 ERE 的超集,但是 BRE 有几个符号上的不兼容(以及更多的限制)。我们首先描述 ARE 和 ERE 形式,描述那些只适用于 ARE 的特性,然后描述 BRE 的区别是什么。
注意
PostgreSQL 接受哪种形式的正则表达式,可以通过设置运行时参数 regex_flavor(在第 16.4 节中描述)来选择。通常的设置是
advanced,但为了与
PostgreSQL 7.4 之前的版本最大程度地向后兼容,也可以选择 extended。
一个正则表达式被定义为一个或更多分支,它们之间被|分隔。只要能匹配其中一个分支的东西都能匹配正则表达式。
一个分支是零个或多个量化原子或约束,连接在一起。它匹配第一个的匹配项,然后是第二个的匹配项,依此类推;一个空分支匹配空字符串。
一个量化原子是一个原子,后面可以跟一个量词。没有量词时,匹配一次原子所匹配的内容;有量词时,按量词指定的次数匹配原子所匹配的内容。原子可以是表 9.12列出的任何一种形式。可用量词及其含义见表 9.13。
一个约束匹配一个空串,但只是在满足特定条件下才匹配。约束可以在能够使用原子的地方使用,只是它不能跟着量词。简单的约束在表 9.14里显示;更多的约束稍后描述。
表 9.12. 正则表达式原子
| 原子 | 描述 |
|---|---|
(re) | (其中re是任意正则表达式)匹配re所匹配的内容,并记录该匹配,以备输出结果 |
(?:re) | 同上,但匹配不被记录以供报告(一组“不捕获的”圆括号)(仅 ARE) |
. | 匹配任意单个字符 |
[chars] | 一个方括号表达式,匹配chars中的任意一个(详见第 9.6.3.2 节) |
\k | (其中k既不是字母也不是数字)把该字符视为普通字符并匹配它,例如,\\匹配反斜线字符 |
\c | 其中c是字母或数字(后面可能还有其他字符),这是一个转义,参见第 9.6.3.3 节(仅适用于 ARE;在 ERE 和 BRE 中,它匹配c) |
{ | 如果后面跟着非数字字符,则匹配左花括号{;如果后面跟着数字,则是bound的开头(见下文) |
x | 其中x是一个没有其它意义的单个字符,则匹配该字符 |
RE 不能以反斜线(\)结尾。
注意
请记住,反斜线(\)在PostgreSQL字符串常量中本来就有特殊含义。要写一个包含反斜线的模式常量,必须在语句中写两个反斜线。
表 9.13. 正则表达式量词
| 量词 | 匹配 |
|---|---|
* | 一个由原子的 0 次或更多次匹配组成的序列 |
+ | 一个由原子的 1 次或更多次匹配组成的序列 |
? | 一个由原子的 0 次或 1 次匹配组成的序列 |
{m} | 一个由原子的正好m次匹配组成的序列 |
{m,} | 一个由原子的m次或更多次匹配组成的序列 |
{m,n} | 一个由原子的从m次到n次(包括)匹配组成的序列;m不能超过n |
*? | *的非贪婪版本 |
+? | +的非贪婪版本 |
?? | ?的非贪婪版本 |
{m}? | {m}的非贪婪版本 |
{m,}? | {m,}的非贪婪版本 |
{m,n}? | {m,n}的非贪婪版本 |
使用 {...}
的形式被称为界限。界限中的数字 m 和 n
是无符号十进制整数,允许的值从 0 到 255(含)。
非贪婪量词(仅适用于 ARE)与对应的普通(贪婪)量词匹配相同的可能内容,但优先选择最少的匹配次数,而不是最多的匹配次数。详见第 9.6.3.5 节。
注意
一个量词不能紧跟在另外一个量词后面。量词不能作为表达式或者子表达式的开头,也不能跟在^或者|后面。
表 9.14. 正则表达式约束
| 约束 | 描述 |
|---|---|
^ | 在字符串开头匹配 |
$ | 在字符串末尾匹配 |
(?=re) | 正向前瞻在匹配
re 的子串开始的任何位置匹配(仅限 ARE) |
(?!re) | 负向前瞻在没有子串匹配
re 开始的任何位置匹配(仅限 ARE) |
先行约束不能包含反向引用(参见第 9.6.3.3 节),其中的所有圆括号都视为非捕获圆括号。
9.6.3.2. 方括号表达式 #
方括号表达式是一个由
[] 括起来的字符列表。它通常匹配列表中的任意单个字符(但见下文)。如果列表以
^ 开头,则匹配任意一个不在列表其余部分中的单个字符。如果列表中的两个字符由
- 分隔,这是按整理序列位于这两个字符之间(含)的完整字符范围的简写形式,例如在 ASCII 中
[0-9] 匹配任意十进制数字。两个范围共享一个端点是非法的,例如
a-c-e。范围非常依赖于整理序列,因此可移植的程序应当避免依赖它们。
想在列表中包含字面字符],可以让它做列表的首字符(如果使用了^,需要放在其后)。想在列表中包含字面字符-,可以让它做列表的首字符或者尾字符,或者一个范围的第二个端点。想在列表中把字面字符-当做范围的起点,把它用[.和.]包围起来,这样它就成为一个排序元素(见下文)。除了这些字符本身、一些用[的组合(见下段)以及转义(只在 ARE 中有效)以外,所有其它特殊字符在方括号表达式里都失去它们的特殊含义。特别是,在 ERE 和 BRE 规则下\不是特殊的,但在 ARE 里,它是特殊的(引入一个转义)。
在一个方括号表达式里,一个排序元素(一个字符、一个被当做一个单一字符排序的多字符序列或者一个表示上面两种情况的排序序列名称)包含在[.和.]里面的时候表示该排序元素的字符序列。该序列被当做该方括号列表的一个单一元素。这允许一个包含多字符排序元素的方括号表达式去匹配多于一个字符,例如,如果排序序列包含一个ch排序元素,那么 RE [[.ch.]]*c匹配chchcc的头五个字符。
注意
PostgreSQL当前不支持多字符排序元素。这些信息描述了将来可能有的行为。
在方括号表达式里,包围在[=和=]里的排序元素是一个等价类,代表等效于那一个的所有排序元素的字符序列,包括它本身(如果没有其它等效排序元素,那么就好像封装定界符是[.和 .])。例如,如果o和^是一个等价类的成员,那么[[=o=]]、[[=^=]]和[o^]都是同义的。一个等价类不能是一个范围的端点。
在方括号表达式中,用 [: 和 :] 括起的字符类名表示属于该类的所有字符的列表。标准字符类名包括:alnum、alpha、blank、cntrl、digit、graph、lower、print、punct、space、upper、xdigit。它们表示 ctype 中定义的字符类。区域设置可以提供其他字符类。字符类不能用作范围的端点。
方括号表达式有两个特例:[[:<:]] 和 [[:>:]] 是约束,分别匹配单词开头和结尾的空字符串。单词定义为一个前后都没有单词字符的单词字符序列。单词字符是 alnum 字符(由 ctype 定义)或下划线。这是与 POSIX 1003.2 兼容但未由其规定的扩展,在打算移植到其他系统的软件中应谨慎使用。通常更适合使用下文介绍的约束转义;它们并不更标准,但更容易键入。
9.6.3.3. 正则表达式转义 #
转义是以\开头,后面跟着一个字母或数字字符的特殊序列。转义有好几种变体:字符输入转义、字符类简写转义、约束转义以及反向引用。在 ARE 里,如果一个\后面跟着一个字母或数字,但是并未组成一个合法的转义,那么它是非法的。在 ERE 中没有转义:在方括号表达式之外,一个后面跟着字母或数字字符的\只是表示该字符是一个普通的字符,而且在一个方括号表达式里,\是一个普通的字符(后者是 ERE 与 ARE 之间唯一的实际不兼容之处)。
字符输入转义便于在 RE 中指定不可打印或其他不便输入的字符,见表 9.15。
字符类简写转义用来提供一些常用的字符类简写。它们显示在表 9.16中。
约束转义是以转义形式书写的约束,在满足特定条件时匹配空字符串,见表 9.17。
反向引用(\n)匹配数字n指定的被前面的圆括号子表达式匹配的同一个串(参阅表 9.18)。例如,([bc])\1匹配bb或者cc,但是不匹配bc或者cb。RE 中子表达式必须完全在反向引用前面。子表达式以它们的左圆括号的顺序编号。非捕获圆括号并不定义子表达式。
注意
请记住,把模式作为 SQL 字符串常量输入时,转义的前导
\ 需要写成两个。
表 9.15. 正则表达式字符输入转义
| 转义 | 描述 |
|---|---|
\a | 警告(响铃)字符,和 C 中一样 |
\b | 退格,和 C 中一样 |
\B | 反斜线(\)的同义词,用来减少双写反斜线 |
\cX | (其中X是任意字符)低序5位和X相同的字符,它的其他位都是零 |
\e | 整理序列名为 ESC 的字符,若没有该名称则取八进制值 033 的字符 |
\f | 换页,和 C 中一样 |
\n | 换行符,与 C 中相同 |
\r | 回车,和 C 中一样 |
\t | 水平制表符,和 C 中一样 |
\uwxyz | (其中wxyz正好是四个十六进制位)本地字节序中的 Unicode 字符U+wxyz |
\Ustuvwxyz | (其中stuvwxyz正好是八个十六进制位)为假设性的 32 位 Unicode 扩展保留
|
\v | 垂直制表符,和 C 中一样 |
\xhhh | (其中hhh是十六进制位的任意序列)十六进制值为0xhhh的字符(一个单一字符,不管用了多少个十六进制位)
|
\0 | 值为0(空字节)的字符 |
\xy | (其中xy正好是两个八进制位,并且不是一个反向引用)八进制值为0xy的字符 |
\xyz | (其中xyz正好是三个八进制位,并且不是一个反向引用)八进制值为0xyz的字符 |
十六进制位是0-9、a-f和A-F。八进制位是0-7。
字符输入转义总是被当作普通字符。例如,\135是 ASCII 中的],但\135并不终止一个方括号表达式。
表 9.16. 正则表达式字符类简写转义
| 转义 | 描述 |
|---|---|
\d | [[:digit:]] |
\s | [[:space:]] |
\w | [[:alnum:]_](注意包括下划线) |
\D | [^[:digit:]] |
\S | [^[:space:]] |
\W | [^[:alnum:]_](注意包括下划线) |
在方括号表达式中,\d、\s 和 \w 会失去其外层方括号,而 \D、\S 和 \W 则是非法的。(因此,例如 [a-c\d] 等同于 [a-c[:digit:]]。此外,等同于 [a-c^[:digit:]] 的 [a-c\D] 是非法的。)
表 9.17. 正则表达式约束转义
| 转义 | 描述 |
|---|---|
\A | 只在字符串的开头匹配(它与 ^ 的区别见第 9.6.3.5 节) |
\m | 只在一个词的开头匹配 |
\M | 只在一个词的末尾匹配 |
\y | 只在一个词的开头或末尾匹配 |
\Y | 只在不属于单词开头或末尾的位置匹配 |
\Z | 只在字符串的结尾匹配(它与 $ 的区别见第 9.6.3.5 节) |
单词的定义与上文[[:<:]]和[[:>:]]的说明相同。方括号表达式中不允许使用约束转义。
表 9.18. 正则表达式反向引用
| 转义 | 描述 |
|---|---|
\m | (其中 m 是一个非零数字)对第m个子表达式的反向引用 |
\mnn | (其中m是一个非零数字,并且nn是后续的若干数字,并且十进制值mnn不大于此前已出现的捕获右圆括号数)一个到第mnn个子表达式的反向引用 |
注意
八进制字符输入转义与反向引用之间存在固有歧义,按上文提到的启发式规则解决:前导零始终表示八进制转义。单个非零数字,如果后面没有其他数字,始终视为反向引用。不以零开头的多位数字序列,如果前面已有相应的子表达式(即该数字在反向引用的合法范围内),则视为反向引用,否则视为八进制转义。
9.6.3.4. 正则表达式元语法 #
除了上面描述的主要语法之外,还有几种特殊形式和杂项语法。
通常所使用的 RE 风味由
regex_flavor 决定。但这可以被一个导向前缀覆盖。如果任何风味的 RE 以 ***: 开头,RE 的其余部分被当作 ARE。如果任何风味的 RE 以 ***= 开头,RE 的其余部分被当作字面字符串,其中所有字符都被视为普通字符。
一个 ARE 可以以嵌入选项开头:一个序列(?xyz)(这里的xyz是一个或多个字母字符)声明影响剩余 RE 的选项。这些选项覆盖任何先前确定的选项(包括 RE 的语法种类和大小写敏感性)。可用的选项字母在表 9.19中显示。
表 9.19. ARE 嵌入选项字母
| 选项 | 描述 |
|---|---|
b | RE的剩余部分是一个BRE |
c | 大小写敏感的匹配(覆盖操作符类型) |
e | RE的剩余部分是一个ERE |
i | 大小写不敏感的匹配(见第 9.6.3.5 节)(覆盖操作符类型) |
m | n的历史原因的同义词 |
n | 换行敏感的匹配(见第 9.6.3.5 节) |
p | 部分换行敏感的匹配(见第 9.6.3.5 节) |
q | RE 的剩余部分按字面(“加引号”)解释,所有字符都视为普通字符 |
s | 非换行敏感的匹配(默认) |
t | 紧凑语法(默认;见下文) |
w | 逆部分换行敏感(“怪异”)的匹配(见第 9.6.3.5 节) |
x | 扩展语法(见下文) |
嵌入选项在终止该序列的 ) 处生效。它们只能在 ARE 的开头使用,不能在其后面的位置使用。
除了常用的(紧凑)RE 语法(其中所有字符都是有效的)之外,还有一种扩展语法,可以通过指定嵌入选项 x 来使用。在扩展语法中,RE 中的空白字符被忽略,# 和其后换行符(或 RE 结尾)之间的所有字符也被忽略。这样就可以对复杂的 RE
进行分段和注释。这一基本规则有三个例外:
前面有
\的空白字符或#会被保留方括号表达式内的空白或
#会被保留空白和注释在多字符符号中是非法的,例如 ARE 的
(?:或 BRE 的\(
扩展语法的空白字符是空格、制表符、换行符,以及任何属于 space 字符类的字符。
最后,在 ARE 里,方括号表达式外面,序列(?#ttt)(其中ttt是任意不包含一个)的文本)是一个注释,它被完全忽略。同样,这样的东西是不允许出现在多字符符号的字符中间的,例如 (?:。这种注释更像是一种历史产物而不是一种有用的设施,并且它们的使用已经被废弃;请使用扩展语法来替代。
如果开头的 ***= 导向已指定把用户的输入当作字面字符串而不是 RE 处理,那么这些元语法扩展一个都不可用。
9.6.3.5. 正则表达式匹配规则 #
当一个 RE 可以匹配给定字符串的多个子串时,RE 匹配在字符串中最先开始的那个。如果 RE 可以匹配从该点开始的多个子串,其选择由它的偏好决定:要么是最长子串,要么是最短子串。
大多数原子以及所有约束都没有偏好。带圆括号的 RE 与该 RE 具有相同的偏好(可能没有)。带量词
{m}
或
{m}?
的量化原子与原子本身具有相同的偏好(可能没有)。带其他普通量词(包括
m 等于 n 的
{m,n})的量化原子偏好最长匹配。带其他非贪婪量词(包括
m 等于 n 的
{m,n}?)的量化原子偏好最短匹配。一个分支与其第一个有偏好的量化原子具有相同的偏好。由 | 操作符连接的两个或更多分支组成的
RE 偏好最长匹配。
在匹配整个 RE 的规则所施加的约束之下,子表达式也根据它们的偏好匹配最长或最短的可能子串,在 RE 中靠前的子表达式比靠后的子表达式优先。注意,外层子表达式因而比其组成部分的子表达式优先。
量词 {1,1} 和 {1,1}?
可分别用于对一个子表达式或整个 RE 强制最长和最短偏好。
在决定更长或者更短的匹配时,匹配长度是以字符衡量的,而不是排序元素。一个空串会被认为比什么都不匹配长。例如:bb*匹配abbbc的中间三个字符;(week|wee)(night|knights)匹配weeknights的所有十个字符;而(.*).*匹配 abc的时候,圆括号包围的子表达式匹配所有三个字符;当(a*)*被拿来匹配bc时,整个 RE 和圆括号子表达式都匹配一个空串。
如果指定不区分大小写的匹配,其效果近似于字母表中的所有大小写差别都消失了。当存在大小写形式的字母作为普通字符出现在方括号表达式之外时,实际上会转换为包含其大小写形式的方括号表达式,例如x变成[xX]。当它出现在方括号表达式内部时,其所有大小写形式都会加入该表达式,例如[x]变成[xX],[^x]变成[^xX]。
如果指定了换行敏感的匹配,.和使用^的方括号表达式将永远不会匹配换行字符(这样,匹配就不会跨越行,除非 RE 显式安排了跨行匹配)并且^和$除了分别匹配串开头和结尾之外,还将分别匹配换行后面和前面的空串。但是 ARE 转义\A和\Z仍然只匹配串的开头和结尾。
如果指定了部分换行敏感的匹配,那么它影响.和方括号表达式,这个时候和换行敏感的匹配一样,但是不影响^和$。
如果指定了逆部分换行敏感匹配,那么它影响^和$,其作用和在换行敏感的匹配里一样,但是不影响.和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。
9.6.3.6. 限制和兼容性 #
在这个实现里,对 RE 的长度没有特别的限制。但是,那些希望高移植性的程序应该避免使用长度超过 256 字节的 RE,因为 POSIX 兼容的实现可以拒绝接受这样的 RE。
ARE 与 POSIX ERE 实际不兼容的唯一特性是:\在方括号表达式中不会失去特殊含义。其他所有 ARE 特性所使用的语法,在 POSIX ERE 中都是非法的,或其效果未定义或未指定;引导前缀的***语法同样不属于 POSIX 的 BRE 或 ERE 语法。
许多 ARE 扩展借鉴自 Perl,但其中一些经过了整理和修改,也未实现少数 Perl 扩展。需要注意的不兼容之处包括\b、\B、不对末尾换行符作特殊处理、取反的方括号表达式也受换行敏感匹配影响、先行约束中对圆括号及反向引用的限制,以及采用最长或最短匹配而非首次匹配的语义。
ARE 与 PostgreSQL 7.4 之前版本识别的 ERE 语法之间存在两个显著的不兼容之处:
在 ARE 中,
\后跟字母数字字符要么是转义要么是错误,而在以前的版本中,这只是书写该字母数字字符的另一种方式。这应该不会造成太大问题,因为在早期版本中没有理由书写这样的序列。在 ARE 中,
\在[]内仍然是特殊字符,因此方括号表达式中的字面\必须写成\\。
虽然这些差异不太可能给大多数应用带来问题,但必要时可以通过把 regex_flavor
设置为 extended 来避免它们。
9.6.3.7. 基本正则表达式 #
BRE 在几个方面和 ERE 不太一样。在 BRE 中,|、+和?都是普通字符并且没有与它们功能等价的东西。范围的定界符是\{和\},而{和}本身是普通字符。嵌套的子表达式的圆括号是\(和\),而(和)自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,^都是一个普通字符。除非在 RE 结尾或者是圆括号子表达式的结尾,$是一个普通字符。如果*出现在 RE 开头或者是圆括号封装的子表达式开头(前面可能有^),那么它是个普通字符。最后,可以用单数字的反向引用,\<和\>分别是[[:<:]]和[[:>:]]的同义词;在 BRE 中没有其它可用的转义。