string LIKE pattern [ESCAPE escape-character]
string NOT LIKE pattern [ESCAPE escape-character]
如果该
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-14
列出了所有可用于 POSIX 正则表达式模式匹配的操作符。
表 9-14. 正则表达式匹配操作符
操作符
|
描述
|
例子
|
~
|
匹配正则表达式,大小写敏感
|
'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
POSIX
模式语言的详细描述见下文。
带两个参数的
substring
函数,即
substring(
string
from
pattern
)
,提供了抽取一个匹配 POSIX 正则表达式模式的子串的方法。如果没有匹配它返回空值,否则就是文本中匹配模式的那部分。 但是如果该模式包含任何圆括号,那么将返回匹配第一对子表达式(对应第一个左圆括号的) 的文本。如果你想在表达式里使用圆括号而又不想导致这个例外,那么你可以在整个表达式外边放上一对圆括号。 如果你需要在想抽取的子表达式前有圆括号,参阅后文描述的非捕获性圆括号。
一些例子:
substring('foobar' from 'o.b') oob
substring('foobar' from 'o(.)b') o
regexp_replace
函数提供了将匹配 POSIX 正则表达式模式的子串替换为新文本的功能。 它的语法是
regexp_replace
(
source
,
pattern
,
replacement
[
,
flags
])。 如果没有匹配
pattern
,那么返回不加修改的
source
串。 如果有匹配,则返回的
source
串里面的匹配子串将被
replacement
串替换掉。
replacement
串可以包含
\
n
, 其中
\
n
是 1 到 9, 表明源串里匹配模式里第
n
个圆括号子表达式的子串应该被插入, 并且它可以包含
\&
表示应该插入匹配整个模式的子串。如果你需要放一个文字形式的反斜线在替换文本里,那么写
\\
。
flags
参数是一个可选的文本串,它包含另个或更多单字母标志,这些标志可以改变函数的行为。标志
i
指定大小写无关的匹配,而标志
g
指定替换每一个匹配的子串而不仅仅是第一个。支持的标志(但不是
g
)在
表 9-22
中描述。
一些例子:
regexp_replace('foobarbaz', 'b..', 'X')
fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
fooXX
regexp_replace('foobarbaz', 'b(..)', E'X\\1Y', 'g')
fooXarYXazY
regexp_matches
函数返回一个文本数组,该数组由匹配一个 POSIX 正则表达式模式得到的所有被捕获子串构成。其语法是
regexp_matches
(
string
,
pattern
[
,
flags
])。该函数可以不返回任何行、返回一行或者返回多行(见下文的
g
)。如果
pattern
不匹配,该函数不返回行。如果模式不包含圆括号子表达式,则每一个被返回的行都是一个单一元素的文本数组,其中包括匹配整个模式的子串。如果模式包含圆括号子表达式,该函数返回一个文本数组,它的第
n
个元素是匹配模式的第
n
个圆括号子表达式的子串(
"非捕获"
圆括号不计算在内,详见下文)。
flags
参数是一个可选的文本字符串,它包含零个或更多个单字母标志,它们可以改变函数的行为。标志
g
让函数寻找串中的每一个匹配,而不仅仅是第一个,并且为每一个这样的匹配返回一行。支持的标志(但不是
g
)在
表 9-22
中描述。
一些例子:
SELECT regexp_matches('foobarbequebaz', '(bar)(beque)');
regexp_matches
----------------
{bar,beque}
(1 row)
SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
regexp_matches
----------------
{bar,beque}
{bazil,barf}
(2 rows)
SELECT regexp_matches('foobarbequebaz', 'barbeque');
regexp_matches
----------------
{barbeque}
(1 row)
也可以强制
regexp_matches()
通过使用一个子选择来总是返回一行。当你希望所有行都被返回(甚至是不能匹配的行)时,把它用在一个
SELECT
目标列表中会特别有用:
SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;
regexp_split_to_table
把一个 POSIX 正则表达式模式当作一个定界符来分离一个串。它的语法形式是
regexp_split_to_table
(
string
,
pattern
[
,
flags
])。如果没有与
pattern
的匹配,该函数返回
string
。如果有至少有一个匹配,对每一个匹配它都返回从上一个匹配的末尾(或者串的开头)到这次匹配开头之间的文本。当没有更多匹配时,它返回从上一次匹配的末尾到串末尾之间的文本。
flags
参数是一个可选的文本串,它包含零个或更多单字母标志,这些标识可以改变该函数的行为。
regexp_split_to_table
能支持的标志在
表 9-22
中描述。
regexp_split_to_array
函数的行为和
regexp_split_to_table
相同,不过
regexp_split_to_array
会把它的结果以一个
text
数组的形式返回。它的语法是
regexp_split_to_array
(
string
,
pattern
[
,
flags
])。这些参数和
regexp_split_to_table
的相同。
一些例子:
SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', E'\\s+') AS foo;
-------
quick
brown
jumps
(9 rows)
SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', E'\\s+');
regexp_split_to_array
-----------------------------------------------
{the,quick,brown,fox,jumps,over,the,lazy,dog}
(1 row)
SELECT foo FROM regexp_split_to_table('the quick brown fox', E'\\s*') AS foo;
-----
(16 rows)
正如上一个例子所示,正则表达式分离函数会忽略零长度的匹配,这种匹配发生在串的开头或结尾或者正好发生在前一个匹配之后。这和正则表达式匹配的严格定义是相悖的,后者由
regexp_matches
实现,但是通常前者是实际中最常用的行为。其他软件系统如Perl也使用相似的定义。
PostgreSQL
的正则表达式是使用 Henry Spencer 写的一个包来实现的。下面的正则表达式的大部分描述都是从他的手册页中逐字拷贝过来的。
正则表达式(
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
初始时总是推测一个正则表达式遵循 ARE 规则。但是,可以通过为 RE 模式预置一个
embedded option
来选择限制更多的 ERE 或 BRE 规则,如
第 9.7.3.4 节
中所述。这对为期望准确的
POSIX
1003.2 规则的应用提供兼容性很有用。
一个正则表达式被定义为一个或更多
分支
,它们之间被
|
分隔。只要能匹配其中一个分支的东西都能匹配正则表达式。
一个分支是一个或多个
量化原子
或者
约束
连接而成。一个原子匹配第一个,然后后面的原子匹配第二个, 以此类推;一个空分支匹配空串。
一个量化原子是一个
原子
, 后面可能跟着一个
量词
。没有量词的时候,它匹配一个原子, 有量词的时候,它可以匹配若干个原子。一个
原子
可以是在
表 9-15
里面显示的任何可能。 可能的量词和它们的含义在
表 9-16
里显示。
一个
约束
匹配一个空串,但只是在满足特定条件下才匹配。 约束可以在能够使用原子的地方使用,只是它不能跟着量词。简单的约束在
表 9-17
里显示; 更多的约束稍后描述。
表 9-15. 正则表达式原子
原子
|
描述
|
(
re
)
|
(其中
re
是任何正则表达式) 匹配一个对
re
的匹配,匹配将为可能的报告被记下
|
(?:
re
)
|
同上,但是匹配不会为了报告而被记下 (一个
"非捕获"
圆括号集) (只对 ARE)
|
.
|
匹配任意单个字符
|
[
chars
]
|
一个
方括号表达式
, 匹配
chars
中的任意一个(详见
第 9.7.3.2 节
)
|
\
k
|
(其中
k
是一个非字母数字字符) 匹配一个被当作普通字符看待的特定字符, 例如,
\\
匹配一个反斜线字符
|
\
c
|
其中
c
是一个字母数字 (可能跟着其它字符),它是一个
逃逸
, 参阅
第 9.7.3.3 节
(仅对 ARE; 在 ERE 和 BRE 中,它匹配
c
)
|
{
|
如果后面跟着一个字符,而不是数字, 那么就匹配左花括弧
{
;如果跟着一个数字, 那么它是
范围
的开始(见下文)
|
x
|
其中
x
是一个没有其它意义的单个字符,则匹配该字符
|
RE 不能以反斜线(
\
)结尾。
表 9-16. 正则表达式量词
量词
|
匹配
|
*
|
一个由原子的 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.7.3.5 节
。
注意:
一个量词不能紧跟在另外一个量词后面,例如
**
是非法的。量词不能作为表达式或者子表达式的开头,也不能跟在
^
或者
|
后面。
表 9-17. 正则表达式约束
约束
|
描述
|
^
|
串开头的匹配
|
$
|
串末尾的匹配
|
(?=
re
)
|
在匹配
re
的子串开始的任何点的
positive lookahead
匹配(只对 ARE)
|
(?!
re
)
|
在匹配
re
的子串开始的任何点的
negative lookahead
匹配(只对 ARE)
|
(?<=
re
)
|
只要有一个点上有一个子串匹配
re
端,
positive lookbehind
就在这个点上匹配(只对 ARE)
|
(?<!
re
)
|
只要有一个点上没有子串匹配
re
端,
negative lookbehind
就在这个点上匹配(只对 ARE)
|
Lookahead和lookbehind约束不能包含
后引用
(参阅
第 9.7.3.3 节
),
并且其中的所有圆括号都被认为是非捕获的。
方括号表达式
是一个包围在
[]
中的字符列表。它通常匹配列表中的任意单个字符(但见下文)。 如果列表以
^
开头,它匹配任意单个
不
在该列表参与部分中的字符。如果该列表中两个字符用
-
隔开, 那它就是那两个字符(包括在内)之间的所有字符范围的缩写,例如,在
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, 但那里面并没有说明, 而且在准备移植到其他系统里去的软件里一定要小心使用。通常下文描述的约束逃逸更好些(它们并非更标准,但是更容易键入)。
在 RE 可以在给定串中匹配多于一个子串的情况下, RE 匹配串中最靠前的那个子串。如果 RE 可以匹配在那个位置开始 的多个子串,要么是取最长的子串,要么是最短的,具体哪种, 取决于 RE 是
贪婪
的还是
非贪婪
的。
一个 RE 是否贪婪取决于下面规则:
-
大多数原子以及所有约束,都没有贪婪属性(因为它们毕竟无法匹配个数变化的文本)。
-
在一个 RE 周围加上圆括号并不会改变其贪婪性。
-
带一个固定重复次数量词 (
{
m
}
或者
{
m
}?
) 的量化原子和原子自身具有同样的贪婪性(可能是没有)。
-
一个带其他普通的量词(包括
{
m
,
n
}
中
m
等于
n
的情况)的量化原子是贪婪的(首选最长匹配)。
-
一个带非贪婪量词(包括
{
m
,
n
}?
中
m
等于
n
的情况)的量化原子是非贪婪的(首选最短匹配)。
-
一个分支 — 也就是说,一个没有顶级
|
操作符的 RE — 和它里面的第一个有贪婪属性的量化原子有着同样的贪婪性。
-
一个由
|
操作符连接起来的两个或者更多分支组成的 RE 总是贪婪的。
上面的规则所描述的贪婪属性不仅仅适用于独立的量化原子, 而且也适用于包含量化原子的分支和整个 RE。这里的意思是, 匹配是按照分支或者整个 RE
作为一个整体
匹配最长或者最短的可能子串。 一旦整个匹配的长度确定,那么匹配任意特定子表达式的部分就基于该子表达式的贪婪属性进行判断,在 RE 里面靠前的子表达式的优先级高于靠后的子表达式。
一个相应的例子:
SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
结果:123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
结果:1
在第一个例子里,RE 作为整体是贪婪的,因为
Y*
是贪婪的。它可以匹配从
Y
开始的东西,并且它匹配从这个位置开始的最长的串, 也就是,
Y123
。输出是这里的圆括号包围的部分,或者说是
123
。在第二个例子里, RE 总体上是一个非贪婪的 RE,因为
Y*?
是非贪婪的。它可以匹配从
Y
开始的最短的子串,也就是说
Y1
。子表达式
[0-9]{1,3}
是贪婪的,但是它不能修改总体匹配长度的决定; 因此它被迫只匹配
1
。
简而言之,如果一个 RE 同时包含贪婪和非贪婪的子表达式,那么总的匹配长度要么是尽可能长,要么是尽可能短,这取决于给整个 RE 赋予的属性。给子表达式赋予的属性只影响在这个匹配里,各个子表达式之间相互允许
"吃掉"
的多少。
量词
{1,1}
和
{1,1}?
可以分别用于在一个子表达式或者整个 RE 上强制
贪婪或者非贪婪。
当你需要整个RE具有不同于从它的元素推导出的贪婪属性,这是非常有用的。
作为一个例子,
假设我们正在尝试分隔包含一些数字到它们之前和之后的数字和部分的字符串。
我们可能会尝试这样做:
SELECT regexp_matches('abc01234xyz', '(.*)(\d+)(.*)');
Result: {abc0123,4,xyz}
这不工作:第一个
.*
是贪婪的,因此它可以尽可能多的
"吃"
,
剩下的
\d+
在最后可能的位置上匹配最后一个数字。
我们可能会通过使它不贪婪尝试修复:
SELECT regexp_matches('abc01234xyz', '(.*?)(\d+)(.*)');
Result: {abc,0,""}
这也不能工作,因为现在RE作为一个整体是非贪婪的,
并且它尽快结束了整体匹配。
我们可以得到我们想要通过迫使RE作为一个整体是贪婪的东西:
SELECT regexp_matches('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
Result: {abc,01234,xyz}
控制从组件贪婪中分离出RE整体贪婪允许处理可变长度的模式更加灵活。
当决定什么是较长或较短匹配的时候,
匹配长度是以字符衡量的,而不是排序元素。一个空串会被认为比什么都不匹配长。例如:
bb*
匹配
abbbc
的中间三个字符;
(week|wee)(night|knights)
匹配
weeknights
的所有十个字符; 而
(.*).*
匹配
abc
的时候,圆括号包围的子表达式匹配所有三个字符;当
(a*)*
被拿来匹配
bc
时,整个 RE 和圆括号 子表达式都匹配一个空串。
如果声明了大小写无关的匹配,那么效果就好像所有大小写区别在字母表中消失了。如果在多个情况中一个字母以一个普通字符的形式出现在方括号表达式外面,那么它实际上被转换成 一个包含大小写的方括号表达式,也就是说,x 变成 [xX]。 如果它出现在一个方括号表达式里面,那么它的所有大小写的同族都被加入 方括号表达式中,也就是说,
x
变成
[xX]
。当它出现在一个方括号表达式内时,它的所有大小写副本都被加入到方括号表达式中,例如,
[x]
会变成
[xX]
,而
[^x]
会变成
[^xX]
。
如果指定了新行敏感的匹配,
.
和使用
^
的方括号表达式 将永远不会匹配新行字符(这样,匹配就绝对不会跨越新行,除非 RE 显式地安排了这样的情况)并且
^
和
$
除了分别匹配串开头和结尾之外,还将分别匹配新行后面和前面的空串。但是 ARE 逃逸
\A
和
\Z
仍然
只
匹配串的开头和结尾。
如果指定了部分新行敏感的匹配,那么它影响
.
和方括号表达式, 这个时候和新行敏感的匹配一样,但是不影响
^
和
$
。
如果指定了逆新行敏感匹配,那么它影响
^
和
$
,其作用和在新行敏感的匹配里一样,但是不影响
.
和方括号表达式。这个并不是很有用,只是为了满足对称性而提供的。
在这个实现里,对 RE 的长度没有特别的限制。但是,那些希望高移植性的程序应该避免使用长度超过 256 字节的 RE,因为 POSIX 兼容 的实现可以拒绝接受这样的 RE。
ARE 实际上和 POSIX ERE 不兼容的唯一的特性是在方括号表达式里
\
并不失去它特殊的含义。所有其它 ARE 特性都使用在 POSIX ERE 里面是非法或者是未定义、未声明效果的语法;指示器的
***
就是在 POSIX 的 BRE 和 ERE 之外的语法。
许多 ARE 扩展都是从 Perl 那里借来的(但是有些被做了修改来清理它们),以及一些 Perl 里没有出现的扩展。要注意的不兼容性包括
\b
、
\B
、对结尾的新行缺乏特别的处理、对那些被新行敏感匹配的东西附加的补齐方括号表达式、在 lookahead 约束里对圆括号和后引用的限制以及最长/最短 匹配(而不是第一匹配)的语义。
PostgreSQL
7.4 之前的版本中识别的 ARE 和 ERE 语法存在两个非常明显的不兼容:
BRE 在几个方面和 ERE 不太一样。在 BRE 中,
|
、
+
和
?
都是普通字符并且没有与它们功能等价的东西。范围的定界符是
\{
和
\}
, 因为
{
和
}
本身是普通字符。嵌套的子表达式的圆括号是
\(
和
\)
,因为
(
和
)
自身是普通字符。除非在 RE 开头或者是圆括号子表达式开头,
^
都是一个普通字符。 除非在 RE 结尾或者是圆括号子表达式的结尾,
$
是一个普通字符。如果
*
出现在 RE 开头或者是圆括号封装的子表达式开头 (前面可能有
^
),那么它是个普通字符。最后,可以用单数字的后引用,
\<
和
\>
分别是
[[:<:]]
和
[[:>:]]
的同义词;在 BRE 中没有其它可用的逃逸。