[bash]正则表达式、BRE模式

来源:互联网 发布:怎样注册淘宝账户 编辑:程序博客网 时间:2024/05/22 04:40

1. 正则表达式引擎:

    1) 正则表达式用于匹配文本,经常和sed和gawk配合使用来过滤文本;

    2) 正则表达的类型:类型主要是由实现正则表达式的引擎来实现的,比如Java的正则表达式有Java版本实现的引擎,MySQL有它自己的正则表达式实现,而Linux的正则表达式的实现使用了POSIX的BRE引擎和ERE引擎;

    3) BRE:Basic Regular Expression Engine,基本正则表达式引擎;

    4) ERE:Extened Regular Expression Engine,扩展正则表达式引擎;

    5) 大多数Linux工具都至少符合BRE标准,但也有些工具,如sed并没有完全实施BRE的全部标准,因为sed追求处理数据流的速度,因此牺牲了一部分对BRE的实现;

    6) 接下来主要讲解BRE模式的定义;


!!BRE模式的正则表达式的定义


2. 纯文本:

    1) 纯文本的匹配是区分大小写的;

    2) 正则表达式的匹配不管模式出现在数据流中的具体位置,主要匹配成功就立马将字符串回传给Linux工具;

    3) 只要文本出现就匹配成功,不管数据流中模式文本紧接的剩下的字符,例如模式是book,那么books也会匹配上,books里面包含了book这个模式字符串,相反模式books无法匹配上book;

    4) 纯文本模式也可以是数字和空格,并且空格可以连续出现;

    5) 纯文本匹配不需要转义,所有能直接进行纯文本匹配的字符包括英文字母、空格、数字着三类;


3. 特殊字符:

    1) 共有11种,分别是()、[]、{}、$、\、?、|、*、^、+、.

    2) 这些特殊字符不能在正则表达式中单独使用,他们有特殊的意义;


4. 转义字符:

    1) 如果想将一些特殊的字符作文纯文本字符进行匹配就要使用\进行转义;

    2) 比如$想作为纯文本,就要使用\进行转义,\$就代表普通文本$;

    3) 有些字符虽然不是BRE的特殊字符,如正斜杠/,但是要将其作为普通纯文本字符匹配也要进行转义,\/才表示纯文本/;

    4) 像\本身要作为纯文本字符匹配也要转义,\\才表示真正的纯文本\;


5. 锚字符:

    1) 锚字符可以将匹配的模式限定到一行的行首或行尾,行首和行尾分别是数据流的两个锚点;

    2) 使用脱字符^将匹配锚点定在行首:

         i. 脱字符即caret character,也就是特殊字符^;

         ii. 脱字符会导致正则表达式只能匹配一行的首部,如果首部没有出现匹配模式则会被过滤掉;

         iii. 脱字符一定要作为正则表达式的首字符才会有效,比如sed '^book'就会找一行的行首是否刚好是book,如果不是则会被过滤掉;

         iv. 如果脱字符不是正则表达的行首,则^就会被当做普通的纯文本字符来匹配了,但是当做纯文本字符也是有条件的,如果^没有其它字符则单个^就会被当做纯文本字符,如果^还有其它字符,则必须使用\进行转义才会把^当做纯文本字符;

!!但是不建议省略\的写法,要养成良好的习惯,要将特殊字符当做纯文本字符匹配就一定要使用\进行匹配,不要过多依赖潜规则!!

!!因为如果使用转义,即使^在正则表达式的首位也同样会被当成普通纯文本来处理;

!例如:sed '/\^book/'、sed '/ls \^e/',前者匹配^book,后者匹配ls e;

!!转义符号\是全局有效的;

    3) 行尾锚点$:

         i. 将$作为正则表达式的最后一个字符就能将模式匹配定位到行尾;

         ii. 例如sed '/book$/'就会匹配以book作为结尾的数据流;

         iii. 同样,如果要将$作为普通纯文本还是要使用\转义,全局有效;

    4) 组合锚点:

         i. 将^和$组合使用同时匹配行首和行尾;

         ii. 特殊用法:sed '/^$/d',可以将所有空行删去,这回匹配行首和行尾之间没有任何字符的数据流并删除,所以能达到这种效果;

!!该用法非常常用,因此一定要熟练掌握;


6. 点字符——单占位符.:

    1) 即特殊字符.:它可以匹配任意单个字符(空格什么的都能匹配),除了换行符外;

    2) 它必须匹配一个字符,如果点字符的位置没有字符,则将会被过滤掉;

    3) 例如:sed '/.at/'就是匹配必须包含三个字符并且后两个是at的模式串;


7. 字符组的基本使用方法——单占位符:

    1) 最主要是为了补充点字符所没有的功能,点字符可以匹配单个任意字符,而字符组可以匹配单个限定字符;

    2) 字符组用特殊字符[]来定义,[]内的每个字符都是匹配候选字符,只要该位置和[]内任意一个字符一样那么就匹配成功;

    3) 例如:sed '/[abc]k/',就可以匹配ak、bk、ck,但是和点字符一样,数据流中字符组[...]的位置必须要有一个字符才行,否则就无法匹配成功;

    4) 字符组中可以包含空格,但是空格不能连续,如果在字符组中出现多个连续的空格则会当成一个空格处理!!!

    5) 字符组可以包含几乎一切可显示的字符,只不过有些需要转义,例如^的纯文本字符,要匹配的话就得[\^]这样转义;

    6) 常用的例子:接受大写或者小写的字母,例如sed '/[Yy][Ee][Ss]/';

!!还有就是单词拼错问题,例如:sed '/maint[ea]n[ae]nce/p',就可以把拼错的行找出来


8. 排除字符组:

    1) 只要将脱字符^放到字符组的首位,那么后面的所有字符都是排除匹配的;

    2) 例如:sed '/[^ch]k/',就是匹配k前面不是c和h的模式串

    3) 即使是排除字符组那也是字符组,必须在字符组的位置有一个字符占位,否则仍然不能匹配;


9. 字符组区间:

    1) 如果在字符组内的多个字符刚好落在一个连续的区间内,则可以使用区间符号'-'来进行简写,最典型的例子就是数字了:sed '/[0-9]/',就表示匹配从0到9的任意一个字符;

    2) 既然有区间,那么这些字符实际上是有大小的,这个大小就是字符编码的值,这里使用的是ASCII编码,[left-right]就是指所有left ≤ char ≤ right的char都能匹配;

    3) left必须≤right(ASCII码的大小),否则会直接在命令行上报错;

!!既然只是ASCII码的大小,那么其它字符,如英文字符也是ASCII编码,因此英文字符也可以用区间简写,例如[a-f]等;

    4) 连字符'-'只是一个在字符组内起到特殊作用的符号,只要出现-,BRE就会把它左右两边的字符看成区间的两个端点,因此可以在一个字符组内加入多个区间(通常这几个区间不连续),也可以在区间外加别的字符,例如:[a-ch-z],这样就表示两个区间a-c和h-z,不包括中间的defg,当然也可以[h-zfb-e]就表示区间h-z、区间b-e和f单个字符;


10. 特殊字符组:

    1) 用来表示某种类型的字符的集合,也属于字符组,也只占一位字符;

    2) 特殊字符组一般形式:[[:XXX:]],例如[[:digit:]]就表示单个数字,就跟[0-9]一样,特殊字符组见名知意避免自己构造产生不必要的错误;

    3) BRE特殊字符组:

alpha:任意字母,部分大小写

lower:小写字母

upper:大写字母

digit:数字

alnum:任意字母和数字(字母部分大小写)

blank:空格和制表

space:空白符(空格、制表、NL、FF、VT、CR)

punct:标点符号

print:任意可打印字符


11. 重复标记*:

    1) 将*放在一个字符后面就代表该字符可以重复0次或多次;

    2) 例如sed '/ak*c/'能匹配ac、akc、akkc、akkkc...

    3) 常见的用法也是拼写容错,比如color会携程colour,那么此时只要匹配colou*r,那么这样就能匹配color和colour了;

    4) 还有一种特殊的用法就是'.*'组合,这样就可以匹配中间包含任意多个任意字符的模式了,比如:sed '/a.*c/'那么只要前后有a和c,中间夹任意多个任意字符的模式都行;

    5) *还可以重复任意子表达式,如果*前面还是一个表达式,那么就可以重复该表达式0次或多次,像[a-c]*都行,着就代表字符组[a-c]可以重复任意多次;

0 0
原创粉丝点击