所谓正则表达式就是用来描述某些字符串匹配规则的工具。
一、什么是正则表达式
在程序的设计过程中,用户不可避免的需要进行文本的操作,而处理文本信息的时候通过正则表达式匹配想要的字符,可以避免通过复杂的代码来过滤文本,从而可以大大提高程序的可读性。
二、正则表达式基础
1. 正则表达式原理
通过正则表达式可以过滤文本,它通过定义一些列的元字符,通过元字符配合其他字符来表达一种规则,只有符合该规则的文本才能保留下来,不符合的就会被过滤掉。
所谓元字符是指用来描述字符的字符。元字符的作用在于对字符表达式的内容、转换以及各种操作信息进行描述。而正则表达式就是由各种字符和元字符构成的字符串。
2. 基本正则表达式
2.1 行首定位符“^”
“^”
称为行首定位符,是正则表达式中的定位符之一,用来匹配行首的字符,表示行首的字符是以“^”后面接的那个字符。
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Hello World
My name is random_w
Good
He
EOF`
#过滤以He开头的行
echo "${Str}" | grep "^He"
Output:
$ sh test.sh
Hello World
He
2.2 行尾定位符“$”
行尾定位符用来定位行尾,如下例:
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Hello World
My name is random_w
Good
He
EOF`
#过滤以He结尾的行
echo "${Str}" | grep "He$"
Output:
$ sh test.sh
He
注意:我们可以使用"^$"匹配空行。
2.3 单个字符匹配“.”
圆点用来匹配单个任意字符,包括空格,但是不包括换行符。
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Abc
AAc
BAc
Amc
EOF`
echo "${Str}" | grep "A.c"
Output:
$ sh test.sh
Abc
AAc
Amc
2.4 限定符“*”
星号是正则表达式中的限定符之一,。限定符本身不包含任何字符,它用来指定前一个字符出现的次出,星号表示前一个字符出现任意次数,包括零次。
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Abc
AAc
BAc
Amc
EOF`
#匹配A后面接任意字符,任意次数的值
echo "${Str}" | grep "A.*"
Output:
$ sh test.sh
Abc
AAc
BAc
Amc
2.5 字符集匹配“[]”
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Abc
AAc
BAc
Amc
EOF`
#匹配ABc AAc
echo "${Str}" | grep "A[BA]c"
Output:
$ sh test.sh
AAc
注意:对于连续数字或者字母可以使用“-”来表示一个范围,如[1-10]表示匹配一到十中的任意字符。
2.6 字符集不匹配“[^]”
当中括号里面有一个"^"时,表示匹配除括号里面出现的字符以外的其他字符。
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Abc
AAc
BAc
Amc
EOF`
echo "${Str}" | grep "A[^BA]c"
Output:
$ sh test.sh
Abc
Amc
注意:当星号和圆点等字符位于匹配集中时,便成为了普通字符,只有字面意义,没有特殊含义。
下表列出了其他基本的正则表达式:
元字符 | 说明 | 举例 |
---|---|---|
\(\) | 定义子表达式的开始和结束的位置。在后续正则表达式中可以通过转义的序号来引用子正则表达式。最多可以定义9个子正则表达式,通过\1~\9来引用。 | 如:"\(love\).*\1 ",表示匹配两个love中包含任意字符的文本行,其中\1表示引用前面的love |
x\{m,n\} | 区间表达式,匹配字符x重复出现的次数区间。其中x\{n}\ 表示最多重复n次,x\{m,\} 表示最少重复m次,x\{m,n\} 表示重复m~n次 | 如:“a\{2,3\} ”表示匹配字符a出现2~3次。 |
\< | 词首定位符 | 如:“<hello”表示匹配以hello开头的单词 |
\> | 词尾定位符 | 如:“>hello”表示匹配以hello结尾的单词 |
3. 扩展正则表达式
扩展正则表达式支持比基本正则表达式更多的元字符,但是扩展正则表达式对某些基本正则表达式所支持的元字符并不支持。
3.1 限定符“+”
加号和星号类似,也是一个用来限定字符出现的次数的,但是加号修饰的字符至少出现依次。
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Abc
AAc
BAc
Amc
EOF`
echo "${Str}" | egrep "A+"
Output:
$ sh test.sh
Abc
AAc
BAc
Amc
注意:grep命令使用的基本正则表达式,egrep使用的是扩展正则表达式。
3.2 限定符“?”
限定符问好,表示前面的字符出现一次或者零次。
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Abc
AAc
BAc
Amc
EOF`
echo "${Str}" | egrep "A?c"
Output:
$ sh test.sh
Abc
AAc
BAc
Amc
3.3 竖线"|“和圆括号”()"
竖线表示匹配多个正则表达式,也就是或的意思,语法为:
expression1|expression2|expression3|...|expressionn
圆括号用来表示一组可选的集合,竖线和圆括号经常一起使用。
#! /usr/bin/env bash
#给数组赋值
Str=`cat <<EOF
Abc
AAc
BAc
Amc
EOF`
echo "${Str}" | egrep "(Abc|Amc|BAc)"
Output:
$ sh test.sh
Abc
BAc
Amc
注意:扩展正则表达式取消了子表达式“()”和次数表达式“{m,n}”语法符号的转义符号引用语法,因此在使用这两种语法的时候不需要加反斜杠转义。
4. Perl正则表达式
在Shell中的grep和egrep都支持Perl正则表达式。
4.1 数字匹配\d
符号\d匹配0~9中的任意数字字符,等价于表达式[0-9]。
4.2 非数字匹配\D
符号\D和\d的作用正好相反,他匹配一个非数字字符等价于[^0-9]
4.3 空白字符匹配\s
符号\s匹配任何空白字符,包括空格、制表符以及换页符等,等价于[\f\n\r\t\v]
4.4 非空白字符匹配\S
符号\S匹配任何非空字符,等价于[^\f\n\r\t\v]
5. 正则表达式的字符集
前面说了使用中括号可以作为一个字符集,同样我们可以使用POSIX字符集。POSIX字符集是为了不同国家的字符编码保持一致而定义的特殊字符集。
下表为常用的POSIX字符集:
字符类 | 说明 |
---|---|
[:alnum:] | 匹配任意一个字母或者数字。 |
[:alpha:] | 匹配任意一个字母 |
[:digit:] | 匹配任意一个数字 |
[:lower:] | 匹配任意一个小写字母 |
[:upper:] | 匹配任意一个大写字母 |
[:space:] | 匹配任意一个空白字符 |
[:blank:] | 匹配空格和制表符 |
[:graph:] | 匹配任意一个看得见的打印字符,不包括空白字符 |
[:print:] | 匹配任何一个可以打印的字符,包括空白字符,但不包括控制字符、字符串结束符“\0”、EOF文件结束符(-1) |
[:cntrl:] | 匹配任何一个控制字符,即ASCII字符集中的前32个字符。 |
[:punct:] | 匹配任何一个标点符号 |
[:xdidit:] | 匹配十六进制数字 |
与其他普通字符一样,上表中的字符类也需要放到方括号中使用,例如[[:alnum:]]与[a-zA-Z0-9]等价。
三、正则表示运算符的优先级
正则表达式按照从左到右的顺序进行计算,并且遵循一定的优先级,这一点与算术运算符类似,下表从高到低列出了正则表达式的优先级。
运算符 | 说明 |
---|---|
|转义符 | |
[] | 方括号表达式 |
() | 分组 |
*、+、?、{m}、{m,}、{m,n} | 限定符 |
普通字符 | 按照从左到右的顺序 |
^、$ | 定位符 |
| | 或运算符 |
四、grep命令
grep命令的名称来自于全局搜索正则表达式并打印文本行的缩写,grep命令的语法如下:
grep [oprion] pattern [file...]
option表示选项如下表,pattern表示要匹配的模式,file表示一系列的文件名称。grep命令会从一个或者多个文件中搜索满足指定模式的文本行,并打印出来。
选项 | 说明 |
---|---|
-c | 只打印匹配到的文本行的行数,不显示匹配的内容 |
-i | 匹配时忽略字母的大小写 |
-h | 当搜索多个文件时,不显示匹配文件名前缀 |
-l | 只列出含有匹配的文本行的文件名,而不显示具体的内容 |
-n | 列出所有的匹配的文本行,并显示行号 |
-s | 不显示关于不存在或者无法读取文件的错误信息 |
-v | 只显示不匹配的文本行 |
-w | 匹配整个单词 |
-x | 匹配整个文本行 |
-r | 递归搜索,不仅搜索当前目录,还要搜索其他各级子目录 |
-q | 禁止输出任何匹配结果,而是以退出状态码的形式表示搜索是否成功,其中0表示匹配到了内容。 |
-b | 打印匹配的文本行到文件头的偏移量,以字节为单位 |
-E | 支持扩展正则表达式 |
-P | 支持Perl正则表达式 |
-F | 不支持正则表达式,将模式按照字面意思匹配 |