《Linux命令行与shell脚本编程大全》第20章
- 2023-02-13 16:50:00
- 胡爱荣
- 原创 419
1. 定义正则表达式
正则表达式是你所定义的模式模板(pattern template),Linux工具可以用它来过滤文本。Linux工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉。
例如:星号通配符允许你只列出满足特定条件的文件
正则表达式的类型
Linux中的不同应用程序可能会用不同类型的正则表达式。这其中包括编程语言(Java、Perl和Python)、Linux实用工具(比 如sed编辑器、gawk程序和grep工具)以及主流应用(比如MySQL和PostgreSQL数据库服务器)。
在Linux中,有两种流行的正则表达式引擎:
1) POSIX基础正则表达式(basic regular expression,BRE)引擎
2) POSIX扩展正则表达式(extended regular expression,ERE)引擎
sed编辑器只符合了BRE引擎规范的子集,gawk程序用ERE引擎来处理它的正则表达式模式。
2. 定义BRE模式
2.1 纯文本
原则1:正则表达式模式都区分大小写。
正则表达式中使用空格和数字
匹配多个连续空格的正则表达式:
2.2 特殊字符
正则表达式可以识别以下特殊字符:
. * [ ] ^ $ { } \ + ? | ( )
如果要用某个特殊字符作为文本字符,就必须使用反斜线\进行转义。反斜线本身也是特殊字符,要在正则表达式中使用它就必须对它转义,这样就会有2个反斜线。
虽然正斜线不是正则表达式的特殊字符,但要使用正斜线也要进行转义。
2.3 锚字符
默认情况下,当指定一个正则表达式模式时,只要模式出现在数据流中的任何地方,它就能匹配。有两个特殊字符可以用来将模式锁定在数据流中的行首或行尾。
锁定在行首
脱字符(^)定义从数据流中文本行的行首开始的模式,即要用脱字符,就必须将它放在正则表达式中指定的模式前面。
由于脱字符出现在正则表达式模式的尾部,sed编辑器会将它当作普通字符来匹配。
锁定在行尾
使用特殊字符美元符号$ 定义行尾锚点,放在文本模式之后指明数据行必须以该文本模式结尾。
组合锚点
可以在同一行中将行首锚点和行尾锚点组合在一起使用。
过滤数据流中的空白行:
2.4 点号字符
特殊字符点号用来匹配除换行符之外的任意单个字符。它必须匹配一个字符,如果在点号字 符的位置没有字符,那么模式就不成立。
2.5 字符组
字符组:限定待匹配的具体字符。使用方括号来定义一个字符组。
单个表达式中用多个字符组。
字符组中使用数字:
匹配邮编出错的示例:
如果要确保只匹配五位数,就必须将匹配的字符和其他字符分开,要么用空格,要么指明行首和行尾。
字符组最常用的用法是解析拼错的单词:
2.6 排除型字符组
查找字符组中没有的字符,可以在字符组的开头加个脱字符^。
2.7 区间
单破折线符号在字符组中表示字符区间,只需要指定区间的第一个字符、单破折线以及区间的最后一个字符就可以了。
若区间中含有字母,字母出现在数据中的任何位置,该模式都不成立。
单个字符组指定多个不连续的区间:如下面的例子中允许区间a-c、h-m中的字母出现在at文本前,但不允许出现d-g的字母。
2.8 特殊的字符组
2.9 星号
在字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次。
在可能出现的额外字母后面放个星号将允许接受拼错的单词。
字符组+星号示例:
点号+星号特殊字符组合起来可以匹配任意数量的任意字符,如下:
3. 扩展正则表达式
POSIX ERE模式包括了一些可供Linux应用和工具使用的额外符号。gawk程序能够识别ERE 模式,但sed编辑器不能。
3.1 问号
问号表明前面的字符可以出现0次或1次,它不会匹配多次出现的字符。
3.2 加号
加号表明前面的字符可以出现1次或多次,但必须至少出现1次。如果该字符没有出现,那么模式就不会匹配。
3.3 使用花括号
间隔(interval):ERE中的花括号允许你为可重复的正则表达式指定一个上限。
可以使用两种方式来指定区间:
1) m:正则表达式准确出现m次。
2) m, n:正则表达式至少出现m次,至多n次。
注意:必须指定gawk程序的--re- interval 命令行选项才能识别正则表达式间隔。
3.4 管道符号
管道符号允许你在检查数据流时,用逻辑OR方式指定正则表达式引擎要用的两个或多个模 式。如果任何一个模式匹配了数据流文本,文本就通过测试。如果没有模式匹配,则数据流文本匹配失败。
3.5 表达式分组
正则表达式模式也可以用圆括号进行分组。
4. 正则表达式实战
目录文件计数示例:
运行结果:
验证电话号码示例:
^\(?:脱字符用来表明数据的开始。由于左圆括号是个特殊字符,因此必须将它转义成普通字符。 问号表明左圆括号可能出现,也可能不出现。
[2-9][0-9]{2}:要求第一个字符是2~9的数字,后跟任意两位数字。
\)?:在区号后面,收尾的右圆括号可能存 在,也可能不存在。
(| |-|\.):在区号后,存在如下可能:有一个空格,没有空格,有一条单破折线或一个点。第一个管道符号紧跟在左圆括号后,用来匹配没有空格的情形。必须将点字符转义,否则它会被解释成可匹配任意字符。
[0-9]{3}:紧接着是3位号码。
( |-|\.):在电话号码之后,你必须匹配一个空格、一条单破折线或一个点。
[0-9]{4}$:最后,必须在字符串尾部匹配4位本地电话分机号。