grep中的正则表达式
曲直
wangquzhi@gmail
December18,2010
正则表达式是一个非常有用的工具。然而,现在正则表达式却有很多流派,它们之间往往有一些琐碎且微小的差别。这个问题确实讨厌。所以个人感觉有必要对不同范围内用到的正则表达式做一些总结。本文中就主要对GNU grep中使用的正则表达式的特性进行了罗列。实际上本文的内容主要来自GNU grep的manpage中关于regular expression一节,你甚至可以认为它就是一篇译文。但在翻译的过程中,对于我个人感到有些不太清晰的地方,又加入了个人的解释。虽然自己看得懂英文,但是毕竟看中文更为习惯一些,这也正是写本文的原因。当然,由于本人仅是一名Linux的爱好者,并非专业人士,自身的水平确实十分有限,难免会有一些不恰当甚至是错误的地方。如果本文在不对读者造成迷惑的基础上能对读者有所帮助,这将是我无比的荣幸。
1
grep支持两种正则表达式:基本表达式(basic)和扩展表达式(extended)。
正则表达式最基本的构造单元是那些匹配单个字符的正则表达式。包括字
母和数字的大多数的字符,都能够直接用来匹配自身。而对于有着特殊意义的
元字符(meta-character),要匹配自己,就必须在前面加上一个反斜杠''\''。
小数点''.''可以用来匹配任意单个字符。
1字符类和括号表达式
括号表达式(bracket expression)指的是一个用一对方括号''[''和'']''括起
来的字符列表。它可以用来匹配任意单个列表中的字符;如果字符列表的第一
个字符是一个补字号'''',那么这个表达式则用来匹配任意不在这个字符列表正则表达式任意内容
中的单个字符。例如正则表达式''[0123456789]''就可以用来匹配任意一个数字。
在括号表达式中,可以包含一个范围表达式(range expression)。一个
范围表达式由一个连词符''-''连接两个字符构成。它可以用来匹配任意顺序位于
这两个字符之间并包括这两个字符范围内的单个字符。在确定上述字符顺序时
将使用当地语言环境(locale)定义的字符集顺序。例如,在缺省C locale情况下,''[a-d]''和''[abcd]''是等价的。然而还有许多字符环境是以字典顺序对字符进
行排序的,如果是这样,那么''[a-d]''将不与''[abcd]''等价;例如,它很可能会等
价于''[aBbCcDd]''。为了使括号表达式能够获得传统性的解释,你可以将环境变
量LC_ALL赋值为C。
有一些特定的字符类已经提前作了定义。它们都是根据自身含义来命
名的。它们是:[:alnum:],[:alpha:],[:cntrl:],[:digit:],[:graph:],[:lower:],[:print:],[:punct:],[:space:],[:upper:]和[:xdigit:]。例如:[[:alnum:]]等价于[0-
9A-Za-z](要注意方括号也是字符类名字的一部分,在使用它们的时候还要再
额外写上一对方括号作为括号表达式界限)。在括号表达式中,大多数的元字
符将会失去它们的特殊意义。如果列表要包含字符'']'',就把它放在列表的第一位。与些类似,要包含'''',
就把它放在列表中非第一位的任意位置。最后,要
包含连字符''-'',就把它放在最后。
2锚字符
锚字符(Anchoring)指补字符''''和美元符号''$''。它们分别代表一行的行
首和行尾位置(注意这里指的是一个位置,而不是一个字符)。
2
3反斜杠和特殊表达式
''\<''和''\>''分别用来匹配一个单词的开头和结尾位置。''\b''用来匹配一个单词的边缘位置。而''\B''用来匹配非单词边缘位置。例如''\bcat\b''可以匹配到''cat'',但是不能匹配''staccato''或者''cation''中的''cat''。类似的,''\Bcat\B''则只能匹配到''staccato''中的''cat''。''\w''和[[:alnum:]]等价,而''\W''和[[:alnum:]]等价。
4重复匹配
下面出现的符号叫做重复操作符(repetition operator),一个正则表达式中可以带有一个或多个这样的
重复操作符。
?匹配是可选的,但最多匹配一次。
*之前的项将被匹配0次或多次。
+之前的项将被匹配1次或多次。
{n}之前的项将被匹配n次。
{n,}之前的项将被匹配n次或更多次。
{,m}之前的项将被匹配至多m次。
{n,m}之前的项将被匹配至少n次,至多m次。
5结合性
可以将两个正则表达式结合成一个表达式。这样,得到的表达式就可以用来匹配那些组成新表达式的两个表达式所匹配的字符串所组成的字符串。这个性质可以表示为:
表达式A匹配StringA,表达式B匹配StringB,那么AB就可以匹配StringAS-tringB。
6选择性
可以用''|''将两个表达式结合成一个表达式。这样新的表达式就可以用来匹配组成新表达式的两个表达式所匹配的字符串中的任意一个字符串。这个性质可以表示为:
表达式A匹配StringA,表达式B匹配StringB,A|B就可以匹配StringA或StringB。
3
7优先级
重复性的优先级要高于结合性,而结合性的优先级高于选择性。此外,可以通过使用小括号来掩盖这些优先级规则。将一个表达式用小括号括起来,可以使之成为一个子表达式。
8向前引用和子表达式
可以用''\n''来引用正则表达式中前面第n个用小括号括起来的子表达式所匹配的内容。
9基本正则表达式vs扩展正则表达式
在基本正则表达式中,元字符包括?,+,{,|,(和)。要对它们进行匹配只需在它们前面加上反斜杠。
传统的扩展正则表达式中元字符并不包括{,然而有一些扩展表达式的元字符却包含{。所以,在可移植的脚本中,如果要使用扩展正则表达式(grep -E),最好不要直接使用{,而是用[{]来代替它。
4
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论