正则表达式学习笔记(一)正则表达式入门

正则表达式入门

作为编程语言的正则表达式

以语言做类比

完整的正则表达式由两种字符组成:特殊字符(special characters,例如文件名例子中的*)称为元字符(metacharacters)其他为‘文字’(literal),或者普通文本字符(normal text characters)。

为了便于理解可以把正则表达式想象为普通的语言,普通字符对应语言中的单词,而元字符对应语法。

Egrep元字符

行的起始和结束

脱字符‘^’:代表一行的开始。

美元符号‘$’:代表一行的结束。

这两元字符特别之处在于匹配的不是字符而是文本位置。

要养成按字符来理解正则表达式的习惯,例如:

不要这样:‘^cat’匹配以cat开头的行

而应该这样理解:‘^cat’匹配的是以c作为一行的第一个字符,紧接着一个a,紧接着一个t的文本。

字符组

匹配若干字符之一

如果我们需要搜索的单词是'grey',但又不确定该单词是否写作‘gray’,就可以使用正则表达式结构体‘[....]’。它允许使用这列出在某处期望匹配的字符,通常被称作字符组(character class)。

如[ea]匹配'e'或者‘a’。请注意,在字符组以外,普通字符都有‘接下来是’的意思,字符组内部的情况则完全不同,它是‘或’的意思。

在字符组内部,字符组元字符‘-’表示一个范围:例如‘[0-9a-z]’匹配数字和小写字母。请注意‘-’只有在字符组内部并且在字符普通字符中间时才是元字符。

排除型字符组

[^....]匹配任何一个未被列出的字符,注意不是‘不要匹配列出的字符’。如‘[^1-6]’匹配一个1到6以外的一个字符。

用点号匹配任意字符

元字符'.',是用来匹配任意字符的字符组的简便写法。

某些可能造成错误的情况:‘34[.-!]’中的‘.’不是元字符,而是普通字符,注意此时的‘-’是用来表示范围的,不是普通字符。

多选结构

‘|’是一个非常简洁的元字符,它的意思是‘或’。依靠它,我们可以把不同的子表达式组合成一个总的表达式,而这个总表达式又能够匹配任意的子表达式。子表达式被称为多选分支。

例如‘tom|price’,匹配tom或者price。我们可以把'gr[ea]y'写成‘grey|gray’或者‘gr(e|a)y’。注意后者用括号来限定多选结构的范围。多选结构可以包含多个字符,但不能超越括号的范围。

注意:一个字符组只能匹配目标文本中的单个字符,而每个多选结构自身都可能是完整的正则表达式,都可以匹配任意长度的文本。字符组可以算是一门独立的微型语言(例如对于元字符它们有自己的规定),而多选结构是正则表达式主体的一部分。

在一个包含多选结构的表达式中使用脱字符和美元符号要特别小心。区别‘^From|Subject|Date’和‘^(From|Subject|Date)’!

单词分界符

某些版本的egrep支持‘/<’和‘/>’来匹配单词的开始和结尾。它们被称作元字符序列(即由两个字符构成一个元字符)。

可选项元素

元字符‘?’代表一个可选项。把它加在一个字符后面,就表示此处允许出现此字符,不过它的出现并非匹配成功的必要条件。如,‘colu?or’。该元字符与之前介绍的元字符不同的地方在于,它只

作用于之前紧邻的元素。如‘July? (fourth | 4(th)?/)’

其他量词:重复出现

元字符‘+’:之前紧邻的元素出现一个或者多次(至少匹配一次)。

元字符‘*’:之前紧邻的元素出现多次,或者不出现。

‘?’‘+’‘*’统称量词。

注意:一个字符组就是一个元素,可以对它直接使用量词而不需要括号。

规定重复出现次数的范围:区间

某些版本的egrep可以使用元字符序列来自定义重现次数的区间。‘{min, max}’

括号及反向引用

前面介绍的括号的两种用途:1.限制多选项的范围。  2.将若干字符组合为一个单元,受量词的作用。

在许多流派的正则表达式中,括号能够记住它们所包含的子表达式匹配的文本。这种特性被叫做反向引用,它允许我们匹配表达式先前部分匹配的同样的文本。

如,‘([0-9])(a-z)/1/2’,其中‘/1’代表‘[0-9]’匹配的内容,‘/2’代表‘[a-z]’匹配的内容。

如,查找重复的单词: egrep -i '\<(a-z+) + \1\>'

神奇的转意符

‘\’,注意在字符组内部转意符无效。

环视

环视结构不匹配任何字符,只匹配文本中的特定位置(环视不占用任何字符)。例如,使用'(?= Jeffrey)Jeff' 得到比'Jeff'更精准的结果。

思考:'(?= Jeffrey)Jeff'和'Jeff(?=rey)'结果是一样的

顺序环视:从左到右查看文本,尝试匹配子表达式,如果能匹配,就返回匹配成功的信息。肯定型顺序环视用'(?=......)'表示。例如,'(?=\d)',表示如果

当前位置右边是数字则匹配成功。

逆序环视:从右向左查看文本。用'(?<=....)'表示,例如'(?<=\d)'表示如果当前位置左边有一个数字,则匹配成功。

环视例子:例如要把所有'Jeffs'换成'Jeff's'

以前的做法:

s/\b(Jerff)(s)\b/$1'$2/g

使用环视:

s/\bJeff(?=s\b)/Jeff'/g

s/(?<=\bJeff)(?=s\b)/'/g.   匹配位置加入撇号

否定环视:匹配成功的条件是子表达式无法匹配。

否定逆序环视: (?<!......)

否定顺序环视:(?!.....)

其他:

1.非捕获型括号:(?: ......)

2.匹配所有空白: \s

3.匹配所以非空白:\S

4.匹配[a-zA-Z0-9]: \w

5.匹配[^a-zA-Z0-9]:\W

6.匹配[0-9]: \d

7.匹配[^0-9]: \D

posted @ 2018-08-25 12:53  Shadowplay  阅读(212)  评论(0编辑  收藏  举报