1. 入门

正则表达式(regular expression)描述了一种字符串匹配的模式( pattern ),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能。

正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

其中正则表达式分为两类:基础的正则表达式扩展的正则表达式

1.1 文本处理三剑客之grep命令

grep : Global search REgular expression and Print out the line

作用 : 文本搜索工具,根据用户指定的“模式”对目标文本逐行进行匹配检查;打印匹配到的行

模式 : 由正则表达式字符及文本字符所编写的过滤条件

  • 语法 : grep [OPTIONS] PATTERN [FILE...]

  • 常用选项

    • --color=auto : 对匹配到的文本着色显示

    • -m # : 匹配#次后停止

    • -v : 显示不被pattern匹配到的行

    • -i : 忽略字符大小写

    • -n : 显示匹配的行号

    • -c : 统计匹配的行数

    • -o : 仅显示匹配到的字符串

    • -q : 静默模式,不输出任何信息

    • -A # : after ,显示匹配行之后的#

    • -B # : before, 显示匹配行之前的#

    • -C # : context,前后各#

    • -e : 实现多个选项间的逻辑or关系,如 : grep –e 'cat' -e 'dog' file

    • -w : 匹配整个单词

    • -E : 使用扩展正则表达式(ERE),相当于egrep

    • -F : 不支持正则表达式,相当于fgrep

    • -f file : 根据模式文件处理

    • -r : 递归目录 , 但不处理软链接

    • -R : 递归目录 . 但处理软链接

Centosgrep命令使用过程中,需要注意以下几点

其中附带有四个特殊的元字符

  • \w: 匹配单词成分的字符。是[_[:alnum:]]的同义词。

  • \W : 匹配非单词成分的字符,是[^_[:alnum:]]的同义词。

  • \s : 空白字符,是[[:space:]]的同义词。

  • \S : 匹配非空白字符,是[^[:space:]]的同义词。

  • grep中无法正常识别\t,\n,\r这种类似的空白元字符,如果需要识别,则需要加上-P选项,通过PCRE模式进行判断筛选

范例 : 取两个文件的相同行,原理便是以f1.txt为中的每一行内容为匹配的模板,分别匹配f2.txt中的内容

[root@centos8 ~]#cat /data/f1.txt
a
b
1
c
[root@centos8 ~]#cat /data/f2.txt
b
e
f
c
1
2
[root@centos8 ~]#grep -f /data/f1.txt /data/f2.txt
b
c
1

范例 : 对各个磁盘分区进行排序

df | grep '^/dev/sd' |tr -s ' ' %|cut -d% -f5|sort -n|tail -1

范例 : 获取已经网络链接状态为ESTASBLISH 的客户端前三的IP,并进行排序

[root@centos8 ~]#ss -nt | grep "^ESTAB" |tr -s ' ' : |cut -d: -f6|sort |uniq -c|sort -nr|head -n3
3 10.0.0.1
1 172.16.4.100
1 172.16.31.188

范例 : 获取ifconifg 命令中的所有IP

[root@centos8 ~]#ifconfig | grep -E '[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]
{1,3}'
inet 10.0.0.8 netmask 255.255.255.0 broadcast 10.0.0.255
inet 172.16.0.123 netmask 255.255.0.0 broadcast 172.16.255.255
inet6 fe80::c11e:4792:7e77:12a4 prefixlen 64 scopeid 0x20<link>
inet 127.0.0.1 netmask 255.0.0.0
[root@centos8 ~]#ifconfig | grep -E '([0-9]{1,3}.){3}[0-9]{1,3}'
inet 10.0.0.8 netmask 255.255.255.0 broadcast 10.0.0.255
inet 172.16.0.123 netmask 255.255.0.0 broadcast 172.16.255.255
inet6 fe80::c11e:4792:7e77:12a4 prefixlen 64 scopeid 0x20<link>
inet 127.0.0.1 netmask 255.0.0.0
[root@centos8 ~]#ifconfig eth0 | grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}'|head -1
10.0.0.8
[root@centos8 ~]#cat regex.txt
([0-9]{1,3}\.){3}[0-9]{1,3}
[root@centos8 ~]#ifconfig | grep -oEf regex.txt
10.0.0.8
255.255.255.0
10.0.0.255
127.0.0.1
255.0.0.0

范例 : 匹配root单词

[root@centos8 ~]#grep -w root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[root@centos8 ~]#grep '\<root\>' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

范例 : 匹配以一个单词开头,同样单词结尾的行

[root@centos8 ~]#grep "^\(.*\)\>.*\<\1$" /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
bash:x:1008:1008::/home/bash:/bin/bash
nologin:x:1011:1011::/home/nologin:/sbin/nologin
​
[root@centos8 ~]#grep -E "^(.*)\>.*\<\1$" /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
bash:x:1008:1008::/home/bash:/bin/bash
nologin:x:1011:1011::/home/nologin:/sbin/nologin
​
[root@centos8 ~]#egrep "^(.*)\>.*\<\1$" /etc/passwd
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
bash:x:1008:1008::/home/bash:/bin/bash
nologin:x:1011:1011::/home/nologin:/sbin/nologin

面试题 : 算出所有人的年龄总和

[root@centos8 ~]#cat /data/nianling.txt
xiaoming=20
xiaohong=18
xiaoqiang=22
[root@centos8 ~]#cut -d"=" -f2 /data/nianling.txt|tr '\n' + | grep -Eo ".*[0-9]"|bc
60
[root@centos8 ~]#grep -Eo "[0-9]+" /data/nianling.txt | tr '\n' + | grep -Eo ".*[0-9]"|bc
60
​

2. 基础正则表达式元字符

2.1. 字符匹配

  • . : 匹配任意单个字符

  • [] : 匹配指定范围内的任意单个字符,示例:[wang],[0-9] ,[a-z],[a-zA-Z]

  • [^] : 匹配指定范围外的任意单个字符

  • [:alnum:] : 字母和数字

  • [:alpha:] : 代表任何英文大小写字符,亦即 A-Z, a-z

  • [:lower:] : 小写字母

  • [:upper:] : 大写字母

  • [:blank:] : 空白字符(空格和制表符)

  • [:space:] : 水平和垂直的空白字符(比[:blank:]包含的范围广)

  • [:cntrl:] : 不可打印的控制字符(退格、删除、警铃...)

  • [:digit:] : 十进制数字

  • [:xdigit:] : 十六进制数字

  • [:graph:] : 可打印的非空白字符

  • [:print:] : 可打印字符

  • [:punct:] : 标点符号

范例

[root@centos8 ~]#ls /etc/ | grep 'rc[.0-6]'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
[root@centos8 ~]#ls /etc/ | grep 'rc[.0-6].'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
[root@centos8 ~]#ls /etc/ | grep 'rc[.0-6]\.'
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d

2.2 次数匹配

用在要指定次数的字符后面,用于指定前面的字符要出现的次数、

  • * : 匹配前面的字符任意次,包括0次,贪婪模式 : 尽可能长的匹配

  • .* : 任意长度的任意字符

  • \? : 匹配其前面的字符0或1次,即:可有可无

  • \+ 匹配其前面的字符至少1次,即:肯定有,>=1

  • \{n\} : 匹配前面的字符n

  • \{m,n\} : 匹配前面的字符至少m次,至多n

  • \{,n\} : 匹配前面的字符至多n次,<=n

  • \{n,\} : 匹配前面的字符至少n

范例:

[root@centos8 ~]# echo /etc/ |grep "/etc/\?"
/etc/
[root@centos8 ~]# echo /etc |grep "/etc/\?"
/etc

2.3 位置锚定

位置锚定可以用于定位出现的位置

  • ^ : 行首锚定 , 用于模式的最左侧

  • $ : 行尾锚定 , 用于模式的最右侧

  • ^PATTERN$ : 用于模式匹配整行\

  • ^$ : 空行

  • ^[[:space:]]*$ : 空白行

  • \<\b : 词首锚定用于单词模式的左侧

  • \>\b : 词尾锚定,用于单词模式的右侧

  • \<PATTERN\> : 匹配整个单词

在正则表达式中将数字、字母和下划线,都被认为是单词的一部分。所以当单词边界是数字、字母或者下划线时则直接不匹配。

范例 : 显示单词边界的效果

[root@localhost tmp]# cat test.txt
root
root123
rootabd123
root_123
root@123
root!123
[root@localhost tmp]# grep '\broot\b' test.txt 
root
root@123
root!123
​

范例 : 排除掉空行和#开头的行

[root@centos8 ~]#grep -v '^$' /etc/profile|grep -v '^#'

2.4 分组其他

2.4.1 分组

分组 : ()将多个字符捆绑在一起,当作一个整体处理,如:\(root\)+

后向引用 : 分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为 : \1, \2, \3, ...

\1 : 表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符

示例 :

\(string1\(string2\)\)
\1 :string1\(string2\)
\2 :string2

注意 : 后向引用引用前面的分组括号中的模式所匹配字符,而非模式本身

2.4.2 或者

或者 : \|

示例 :

a\|b #a或b
C\|cat #C或cat
\(C\|c\)at #Cat或cat

范例 : 排除空行和#开头的行

[root@centos6 ~]#grep -v '^#' /etc/httpd/conf/httpd.conf |grep -v ^$
[root@centos6 ~]#grep -v '^#\|^$' /etc/httpd/conf/httpd.conf
[root@centos6 ~]#grep -v '^\(#\|$\)' /etc/httpd/conf/httpd.conf
[root@centos6 ~]#grep "^[^#]" /etc/httpd/conf/httpd.conf

3. 扩展正则表达式元字符

3.1 字符匹配

  • . : 任意单个字符

  • [] : 指定范围的字符,例:[wang],匹配w,a,n,g中任意一个字母

  • [^] : 不在指定范围的字符,例:[^wang] : 表示匹配除w,a,n,g外的字符

  • [:alnum:] : 字母和数字

  • [:alpha:] : 代表任何英文大小写字符,亦即 A-Z, a-z

  • [:lower:] : 小写字母,示例 : [[:lower:]],相当于[a-z]

  • [:upper:] : 大写字母

  • [:blank:] : 空白字符(空格和制表符)

  • [:space:] : 水平和垂直的空白字符(比[:blank:]包含的范围广)

  • [:cntrl:] : 不可打印的控制字符(退格、删除、警铃...)

  • [:digit:] : 十进制数字

  • [:xdigit:] : 十六进制数字

  • [:graph:] : 可打印的非空白字符

  • [:print:] : 可打印字符

  • [:punct:] : 标点符号

3.2 次数匹配

  • * : 匹配前面字符任意次

  • ? : 0或1次

  • + : 1次或多次

  • {n} : 匹配n

  • {m,n} : 至少m,至多n

  • {,n} : 至多n次,没有最少限制

  • {m,} : 最少m次,最多没有限制

3.3 位置锚定

  • ^ :匹配行首对应字符

  • $ : 行尾

  • \<, \b : 单词词首锚定,用于匹配单词模式的左侧。

  • \>, \b : 单词词尾锚定,用于匹配单词模式的右侧。

3.4 分组其他

() : 分组,与基础的正则表达式最大的差别就是少了反斜杠,之后使用后向引用和之前一样

后向引用 : \1,\2, ...

| : 或者

a|b #a或b
C|cat #C或cat
(C|c)at #Cat或cat

4. 字符表示

4.1. 转义字符

字母前面加上反斜线\来表示常见的那些不能显示的 ASCII字符 , 称为转义字符。如 \n 等。

转义字符

意义

ASCII码值(十进制)

\a

响铃(BEL)

007

\b

退格(BS),将当前位置移到前一列

008

\f

换页(FF),将当前位置移到下页开头

012

\n

换行(LF),将当前位置移到下一行开头

010

\r

回车(CR),将当前位置移到本行行头

013

\t

水平制表(HT),(调到下一个TAB位置)

009

\v

垂直制表(VT)

011

\\

代表一个反斜线字符\

092

\'

代表一个单引号(撇号)字符

039

\"

代表一个双引号字符

034

\0

空字符(NULL)

000

\ddd

1到3位八进制数所代表的任意字符

三位八进制

\xhh

1到2位十六进制所代表的任意字符

二位十六进制

4.2. 特殊字符

在正则表达式中,某些字符有特殊意义,需要在它前面添加 \才能当作普通文本字符来使用。

使用正则表达式regex匹配特殊字符(2种方法记忆):

方法1:首先加\匹配该特殊字符本身,然后在转义字符(即\)前加\

方法2:在特殊字符前加\\(或者使用[]) , 特别的\需要使用\\\\来匹配

字符

说明

regex1

regex2

^

匹配输入字符串的开始位置。要匹配 ^字符本身,请使用 \^

\\^

[^]

$

匹配输入字符串的结尾位置。要匹配$字符本身,请使用\$

\\$

[$]

.

匹配除了换行符(\n)以外的任意一个字符。要匹配小数点本身,请使用 \.

\\.

[.]

[]

用来自定义能够匹配多种字符 的表达式。要匹配中括号,请使用 \[\]

\\[

[\\[]

*

修饰匹配次数为 0 次或任意次。要匹配 * 字符本身,请使用\*

\\*

[*]

\

将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。

\\\\

?

修饰匹配次数为 0 次或 1 。要匹配 ?字符本身,请使用 \?

\\?

[?]

+

修饰匹配次数为至少1次。要匹配 +字符本身,请使用 \+

\\+

[+]

{}

修饰匹配次数的符号。要匹配大括号,请使用 \{\}

\\{

[{]

|

左右两边表达式之间 "或" 关系。匹配 |本身,请使用 \|

\\|

[|]

()

标记一个子表达式的开始和结束位置。要匹配小括号,请使用 \(\)

\\(

[(]


参考链接

转义字符,正则表达式,特殊字符,模式匹配_Angela㐅cc的博客-CSDN博客


熊熊