Emacs 正则表达式简介(From 水木清华)
发信人: dddkk (进化的鱼), 信区: Emacs
标 题: Emacs 的正则表达式
发信站: BBS 水木清华站 (Thu Mar 18 20:11:52 2004), 转信
两年多以前翻译的,就是 (info "(emacs)Regexps") 一节。
正则表达式语法
正则表达式(regular expressions, 缩写为regexp)是由几个特殊字符和一些普通
字符组成,一个普通就是一个简单的正则表达式,仅仅可以匹配与自己相同的字符。
而特殊字符包括“$”,“^”, “.”, “*”, “+”, “?”,“[”, “]”
以及 “\”。除非在一个字符前面有“\”,否则正则表达式中的出现的任何其他字符
都是普通字符,(当你在 Lisp 语言的程序中使用正则表达式的时候,每一个“\”都
必须写成两个,请看下面的例子。)
例如,“f”不是特殊字符,是普通字符,因此“f”是一个正则表达式,它仅仅
匹配“f”这个字符串。(不匹配串“ff”。)同样“o”是一个仅仅匹配串“o”的正
则表达式。(当不区分大小写的时候,上面提到的式子也匹配“F”和“O”,而一般
认为它们是“同样的串”,并不是例外。)
两个任意的表达式 A 和 B 可以被连接。结果是一个能够匹配以 A 开始,其余部
分是 B 的字符串的表达式。
举个简单的例子,我们将表达式“f”和“o”连接,得到表达式“fo”,它仅匹
配串“fo”,很简单的。想做些不简单的,你需要使用特殊字符。下面为这些特殊字
符。
特殊字符
“. (Period)”
一个匹配除了换行符(newline)之外任何单个字符的特殊字符。使用连接,我们
可以得到如“a.b”的表达式,它匹配了所有的以“a”开始,以“b”结束的三
个字符的字符串。
“*”
自身不构成表达式的部分;它是个后缀操作符,表示某个前导表达式重复任意次。
比如,“o*”匹配任意个数的“o”(包括没有“o”)。
“*”总是作用于“最少的”可能的前导表达式。于是,“fo*”中,认为“o”是
的重复,而不是“fo”,匹配形如“f”, “fo”, “foo”的串等等。
匹配程序以迅速的、尽可能多的找到重复部分来处理一个带“*”的结构。然后继
续其他部分的处理。如果失败了,为了使剩余的部分能够尽可能的匹配,匹配程
序会回退,放弃一些由“*”匹配的结构。例如,在使用“ca*ar”来匹配串
“caaar”时,“a*”首先试图匹配全部的三个“a”;但余下的部分是“ar”并
且仅有“r”没被匹配,因此这次试图匹配失败。接着选择是用“a*”来匹配两个
“a”,并且匹配成功。
“+”
是一个和“*”相似的后缀操作符,它匹配前导表达式至少一次的出现。例如,
“ca+r”匹配串“car”和“caaaar”,不匹配“cr”,然而“ca*r”可以匹配这
三个串。
“?”
也是一个和“*”相似的操作符,它匹配前导表达式至多一次的出现。例如,
“ca?r”仅仅匹配“car”或“cr”。
“*?, +?, ??”
是前面几个个操作符的非贪心(non-greedy)的变体。正常的“*”, “+”, “?”
操作符是“贪心的(greedy)”,只要总体上能够匹配,这些操作符总是尽可能多
的匹配。当有一个紧跟着的“?”,就是是非贪心的了:将尽可能少的匹配。
“ab*”和“ab*?”都能匹配串“a”和“abbbb”;但如果你试图用它们来匹配
“abbb”时,“ab*”将匹配全部(最长有效匹配),而“ab*?”将仅仅匹配“a”
(最短有效匹配)。
“\{N\}”
指定重复次数为 N 的后缀操作符,一个前导表达式必须恰好匹配了 N 次。例如
“x\{4\}”仅仅匹配串“xxxx”。
“\{N,M\}”
指定重复次数在N和M之间的后缀操作符,就是说它的前导表达式的匹配次数至少
N 次但不能超过 M 次。如果省略 M,表示没有上限,但它的前导表达式至少匹配
N 次。“\{0,1\}”等同于“?”。“\{0,\}”等同于“*”。“\{1,\}”等同于
“+”。
“[ ... ]”
字符集,以“[”开始以“]”结束。最简单的例子,在两个方括号中间的字符就
是这个集合所能匹配的全部。
所以,“[ad]”仅匹配一个“a”或一个“d”,“[ad]*”匹配所有仅由“a”和
“d”构成的串(包括空串)。“c[ad]*r”匹配“cr”,“car”, “cdr”,
“caddaar”,等等。
也可以用一个“-”放在一个开始字符和一个结束字符的中间来在字符集中包含这
个范围。“[a-z]”匹配所有小写 ASCII 字母。范围可以和单独的字符自由的组
合在一起,比如“[a-z$%.]”,匹配了任意的小写字母,或“$”,“%”,以及
“.”。
注意,通常在字符集中的特殊字符不再特殊。而在字符集中的“]”,“-”和
“^”却不这样。
如果想在集中包括“]”,必须把它作为字符集中的第一个字符。例如,“[]a]”
匹配“]”或“a”。想包括“-”,它要是字符集中的第一个或最后一个字符。
或者放在一个范围的后面。如“[]-]”匹配“]”和“-”。
如果想在集包括字符“^”,它可以在除第一个位置以外的任何地方。(在开始
位置,它会把这个字符集取补——看下面。)
当不区分大小写使用范围时,表示范围的两个字符或者都是大写、或者都是小写、
或者都不是字母。混合大小写的范围如“A-z”有点错误定义的意思,在将来的
Emacs 中这个可能会被改变。
“[^ ... ]”
“[^”表示“补集合”,匹配的字符是除掉指定的字符外其他所有的字符。如,
“[^a-z0-9A-Z]”匹配除掉ASCII字母和数字的所有字符。
当“^”在字符集中第一个时,被看作是特殊字符。而跟在“^”后面的字符被看
作是第一个字符(就是说,此处的“-”和“]”将不是特殊的)。
一个补集合可以匹配换行符,除非换行符被指定为补集合中的一个字符。这不同
于某些象“grep”的程序对正则表达式的处理。
“^”
仅仅匹配在文本中行首的那个空串的特殊字符。就是说,“^foo”匹配在行首的
“foo”。
“$”
和“^”相似,但仅匹配行尾的空串。因此“x+$”匹配在行尾的一个或多个“x”
的串。
“\”
有两个作用:引用特殊字符(包括“\”);产生附加的特殊结构。
因为“\”引用特殊字符,“\$”是一个仅匹配“$”的表达式,“\[”是一个仅
匹配“[”的表达式,等等。
关于反斜线
注意:为兼容性考虑,特殊字符,如果在其没有意义的上下文中,将被当作普通
字符。比如:“*foo”中把“*”当作普通字符,因为在它前面没有可以作用的前导表
达式。很少有人会根据这条规则去实践;无论如何,在任何地方都加上引用会更好些。
对于大多数情况,“\”后接任何字符仅仅匹配那个字符。然而,有几个例外:
以“\”开始的两字符序列会有特殊的意思。其中的第二个字符往往是普通字符。下
面是“\”的结构表。
“\|”
指定一个选择。中间有一个“\|”的两个正则表达式 A 和 B,形成了一个可以匹
配 A 或 B 的文本。它首先试图用 A 匹配,如果失败再用 B 去试。
由此,“foo\|bar”仅匹配“foo”或“bar”。
“\|”作用于两边最长的可能的表达式。仅由“\( ... \)”括起来才可以限制
“\|”的分组能力。
Emacs 有全面的回退功能,以处理“\|”的多种的用途。
“\( ... \)”
分组结构,有三个功能:
发信人: dddkk (进化的鱼), 信区: Emacs
标 题: Emacs 的正则表达式
发信站: BBS 水木清华站 (Thu Mar 18 20:11:52 2004), 转信
两年多以前翻译的,就是 (info "(emacs)Regexps") 一节。
正则表达式语法
正则表达式(regular expressions, 缩写为regexp)是由几个特殊字符和一些普通
字符组成,一个普通就是一个简单的正则表达式,仅仅可以匹配与自己相同的字符。
而特殊字符包括“$”,“^”, “.”, “*”, “+”, “?”,“[”, “]”
以及 “\”。除非在一个字符前面有“\”,否则正则表达式中的出现的任何其他字符
都是普通字符,(当你在 Lisp 语言的程序中使用正则表达式的时候,每一个“\”都
必须写成两个,请看下面的例子。)
例如,“f”不是特殊字符,是普通字符,因此“f”是一个正则表达式,它仅仅
匹配“f”这个字符串。(不匹配串“ff”。)同样“o”是一个仅仅匹配串“o”的正
则表达式。(当不区分大小写的时候,上面提到的式子也匹配“F”和“O”,而一般
认为它们是“同样的串”,并不是例外。)
两个任意的表达式 A 和 B 可以被连接。结果是一个能够匹配以 A 开始,其余部
分是 B 的字符串的表达式。
举个简单的例子,我们将表达式“f”和“o”连接,得到表达式“fo”,它仅匹
配串“fo”,很简单的。想做些不简单的,你需要使用特殊字符。下面为这些特殊字
符。
特殊字符
“. (Period)”
一个匹配除了换行符(newline)之外任何单个字符的特殊字符。使用连接,我们
可以得到如“a.b”的表达式,它匹配了所有的以“a”开始,以“b”结束的三
个字符的字符串。
“*”
自身不构成表达式的部分;它是个后缀操作符,表示某个前导表达式重复任意次。
比如,“o*”匹配任意个数的“o”(包括没有“o”)。
“*”总是作用于“最少的”可能的前导表达式。于是,“fo*”中,认为“o”是
的重复,而不是“fo”,匹配形如“f”, “fo”, “foo”的串等等。
匹配程序以迅速的、尽可能多的找到重复部分来处理一个带“*”的结构。然后继
续其他部分的处理。如果失败了,为了使剩余的部分能够尽可能的匹配,匹配程
序会回退,放弃一些由“*”匹配的结构。例如,在使用“ca*ar”来匹配串
“caaar”时,“a*”首先试图匹配全部的三个“a”;但余下的部分是“ar”并
且仅有“r”没被匹配,因此这次试图匹配失败。接着选择是用“a*”来匹配两个
“a”,并且匹配成功。
“+”
是一个和“*”相似的后缀操作符,它匹配前导表达式至少一次的出现。例如,
“ca+r”匹配串“car”和“caaaar”,不匹配“cr”,然而“ca*r”可以匹配这
三个串。
“?”
也是一个和“*”相似的操作符,它匹配前导表达式至多一次的出现。例如,
“ca?r”仅仅匹配“car”或“cr”。
“*?, +?, ??”
是前面几个个操作符的非贪心(non-greedy)的变体。正常的“*”, “+”, “?”
操作符是“贪心的(greedy)”,只要总体上能够匹配,这些操作符总是尽可能多
的匹配。当有一个紧跟着的“?”,就是是非贪心的了:将尽可能少的匹配。
“ab*”和“ab*?”都能匹配串“a”和“abbbb”;但如果你试图用它们来匹配
“abbb”时,“ab*”将匹配全部(最长有效匹配),而“ab*?”将仅仅匹配“a”
(最短有效匹配)。
“\{N\}”
指定重复次数为 N 的后缀操作符,一个前导表达式必须恰好匹配了 N 次。例如
“x\{4\}”仅仅匹配串“xxxx”。
“\{N,M\}”
指定重复次数在N和M之间的后缀操作符,就是说它的前导表达式的匹配次数至少
N 次但不能超过 M 次。如果省略 M,表示没有上限,但它的前导表达式至少匹配
N 次。“\{0,1\}”等同于“?”。“\{0,\}”等同于“*”。“\{1,\}”等同于
“+”。
“[ ... ]”
字符集,以“[”开始以“]”结束。最简单的例子,在两个方括号中间的字符就
是这个集合所能匹配的全部。
所以,“[ad]”仅匹配一个“a”或一个“d”,“[ad]*”匹配所有仅由“a”和
“d”构成的串(包括空串)。“c[ad]*r”匹配“cr”,“car”, “cdr”,
“caddaar”,等等。
也可以用一个“-”放在一个开始字符和一个结束字符的中间来在字符集中包含这
个范围。“[a-z]”匹配所有小写 ASCII 字母。范围可以和单独的字符自由的组
合在一起,比如“[a-z$%.]”,匹配了任意的小写字母,或“$”,“%”,以及
“.”。
注意,通常在字符集中的特殊字符不再特殊。而在字符集中的“]”,“-”和
“^”却不这样。
如果想在集中包括“]”,必须把它作为字符集中的第一个字符。例如,“[]a]”
匹配“]”或“a”。想包括“-”,它要是字符集中的第一个或最后一个字符。
或者放在一个范围的后面。如“[]-]”匹配“]”和“-”。
如果想在集包括字符“^”,它可以在除第一个位置以外的任何地方。(在开始
位置,它会把这个字符集取补——看下面。)
当不区分大小写使用范围时,表示范围的两个字符或者都是大写、或者都是小写、
或者都不是字母。混合大小写的范围如“A-z”有点错误定义的意思,在将来的
Emacs 中这个可能会被改变。
“[^ ... ]”
“[^”表示“补集合”,匹配的字符是除掉指定的字符外其他所有的字符。如,
“[^a-z0-9A-Z]”匹配除掉ASCII字母和数字的所有字符。
当“^”在字符集中第一个时,被看作是特殊字符。而跟在“^”后面的字符被看
作是第一个字符(就是说,此处的“-”和“]”将不是特殊的)。
一个补集合可以匹配换行符,除非换行符被指定为补集合中的一个字符。这不同
于某些象“grep”的程序对正则表达式的处理。
“^”
仅仅匹配在文本中行首的那个空串的特殊字符。就是说,“^foo”匹配在行首的
“foo”。
“$”
和“^”相似,但仅匹配行尾的空串。因此“x+$”匹配在行尾的一个或多个“x”
的串。
“\”
有两个作用:引用特殊字符(包括“\”);产生附加的特殊结构。
因为“\”引用特殊字符,“\$”是一个仅匹配“$”的表达式,“\[”是一个仅
匹配“[”的表达式,等等。
关于反斜线
注意:为兼容性考虑,特殊字符,如果在其没有意义的上下文中,将被当作普通
字符。比如:“*foo”中把“*”当作普通字符,因为在它前面没有可以作用的前导表
达式。很少有人会根据这条规则去实践;无论如何,在任何地方都加上引用会更好些。
对于大多数情况,“\”后接任何字符仅仅匹配那个字符。然而,有几个例外:
以“\”开始的两字符序列会有特殊的意思。其中的第二个字符往往是普通字符。下
面是“\”的结构表。
“\|”
指定一个选择。中间有一个“\|”的两个正则表达式 A 和 B,形成了一个可以匹
配 A 或 B 的文本。它首先试图用 A 匹配,如果失败再用 B 去试。
由此,“foo\|bar”仅匹配“foo”或“bar”。
“\|”作用于两边最长的可能的表达式。仅由“\( ... \)”括起来才可以限制
“\|”的分组能力。
Emacs 有全面的回退功能,以处理“\|”的多种的用途。
“\( ... \)”
分组结构,有三个功能:
|