day28 正则表达式

day28 正则表达式

知识点回顾 ----通配符

通配符在Linux中,是为了提取系统中文件名的信息

通配符: 文件,文件名
正则表达式 : 文件内的数据

关于学习正则

  • 正则表达式这个知识点的学习,在于先学习正则符号的意义,以及如何使用正则表达式提取你所需要的数据
  • 他不象Linux命令一样,有一些固定的语法,也不像搭建服务一样有固定的流程
  • 因此需要练习正则,在不看答案的情况下写出来,以及自己的独立的思考。
  • 加油吧 , yzk
正则的表达式,是数据处理的人去使用,如数据分析师,爬虫工程师,主要是对数据的提取。

# 对于运维人员来说:
提取文件的关键数据,做分析
日志的分析,提取网站的链接

http://www.taobao.com
https://www.jd.com
http://yuchaoit.cn

  • 例如 ps -ef | grep 'nginx'

  • 在学习完正则之后,结合grep(过滤),sed(代替)awk(输出)三剑客命令,去给予一些通用的用法,解决常用的运维需求,例如对日志的提取,我么学习完后在统一正则

  • 正则的表达式是一个知识的体系他需要不断的练习,不断地学习,也就自然的孰能生巧。


正则表达式 描述
\ 反斜线 转义字符,将字符转义化,忽略其特殊的意义
^尖角符 匹配行首
$ 匹配行尾
. 匹配除啦\n 之外的任意的字符
[] 匹配包含【】之中的任意一个字符
[^] 匹配[]里面除外的任意一个字符
[-] 匹配【】指定的范围之内的任意一个字符
匹配之前的一次或者0次
+ 匹配之前的一次或者多次
* 匹配之前的0次或者多次

放大去看图片


什么是正则表达式

  • 正则表达式就是为了处理大量的数据而定义的规则和方法
  • 通过定义这些特殊符号的辅助,我们就可以快速的过滤grep ,替换sed ,输出awk
  • Linux正则表达式一般是处理文件的数据
wwwwwwwwwwwww 
eeeeeeeeeeee
qweqweqweqwe

234134r1234r34t243t

linux的换行符 \n

如何正确的正则的表达式

通常Linux运维的工作,都是面临大量的字符的内容

  • 配置文件
  • 程序输出的代码
  • 命令输出的结果
  • 日志文件

我们常常会有特定的需要,查找出符合工作需要的特定的字符,因此正则表达式就出现了。

  • 正则表达式是一套跪着方法
  • 正则工作时以单位进行,一次处理一行
  • linux 的仅仅三剑客(sed,awk,grep)其他的命令无法的使用。

学习正则的注意的事项

  • 正则表达式应用非常广泛,很多编程语言都支持正则表达式,用于处理字符串提取数据。

  • java
    python
    golang
    javascripts
    
    sed
    awk
    grep
    
  • Linux下普通命令无法使用正则表达式的,只能使用linux下的三个命令,结合正则表达式处理。

    • sed
    • grep
    • awk
  • 通配符是大部分普通命令都支持的,用于查找文件或目录

  • 而正则表达式是通过三剑客命令在文件(数据流)中过滤内容的,注意区别

  • 以及注意字符集,需要设置LC_ALL=C,注意这一点很重要

关于字符集的设置

你会发现很多shell脚本都有一个语句

[root@linux-yzk ~]# locale
LANG=zh_CN.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=
[root@linux-yzk ~]# 


比如你平时喜欢让linux支持中文,如果你的系统编码是中文,很可能导致你的正则出错,因此要还原系统的编码
LANG='zh_CN.UTF-8'

执行一个还原本地所有编码信息的变量
LC_ALL=C

用法如下
[242-yuchao-class01 root ~]#export LC_ALL=C

作用是修改linux的字符集,通过locale命令可以查看本地字符集设置

linux通过如下变量设置程序运行的不同语言环境,如中文、英文环境。

[root@yuchao-tx-server ~]# locale
LANG=en_US.UTF-8
LC_CTYPE="zh_CN.UTF-8"
LC_NUMERIC="zh_CN.UTF-8"
LC_TIME="zh_CN.UTF-8"
LC_COLLATE="zh_CN.UTF-8"
LC_MONETARY="zh_CN.UTF-8"
LC_MESSAGES="zh_CN.UTF-8"
LC_PAPER="zh_CN.UTF-8"
LC_NAME="zh_CN.UTF-8"
LC_ADDRESS="zh_CN.UTF-8"
LC_TELEPHONE="zh_CN.UTF-8"
LC_MEASUREMENT="zh_CN.UTF-8"
LC_IDENTIFICATION="zh_CN.UTF-8"
LC_ALL=zh_CN.UTF-8

一般我们会使用$LANG变量来设置linux的字符集,一般设置为我们所在的地区,如zh_CN.UTF-8

[root@yuchao-tx-server ~]# echo $LANG
en_US.UTF-8

为了让系统能正确执行shell语句(由于自定义修改的不同语言环境,对一些特殊符号的处理区别,如中文输入法,英文输入法下的标点符号等,导致shell无法执行)

我们会使用如下语句,恢复linux的所有的本地化设置,恢复系统到初始化的语言环境。

[root@yuchao-tx-server ~]# export LC_ALL=C

重要的一点把系统的语言的环境改为英文的环境


通配符和正则的区别

从语法上,只有grep , sed ,awk 才能识别正则的符号,其他的都是通配符。

只有用这3个命令的操作,你写下的特殊符号,才是正则表达式---提取数据流的关键信息

其他linux命令的操作,都是通配符的概念,以及------查找文件名

2.从用法上区分

  • 表达式操作的是文件、目录名(属于是通配符)
  • 表达式操作的是文件内容(正则表达式)

3.比如如下符号区别

通配符和正则表达式 都有  *  ?  [abcd] 符号
通配符中,都是用来标识任意的字符
如 ls *.log,可以找到a.log  b.log   ccc.log


正则中,都是用来表示这些符号前面的字符,出现的次数,如

grep 'a*'

实际的案例

通配符,一般用于对文件名的处理,查找文件
如ls命令结合*
意思是匹配任意字符
[root@yuchao-tx-server test]# ls *.log
1.log  2.log  3.log  4.log  5.log


而三剑客,结合*符号,是处理文件内容,如grep
此时的*作用就不一样了

两类、正则表达式符号

为什么会跟你强调这个事

因为grep
awk
sed
在处理正则时,默认也只认识 基础正则表达式

如果你写了分区,或者,这样的符号,必须给grep,加上额外的参数,让它识别这些扩展正则

linux 规范有两类

  • 基本的正则的表达式(BRE)

    BRE对应元字符有 
    ^ $ . [ ] *
    
    其他符号是普通字符
    ; \
    
    • 扩展正则表达式(ERE、extended regular expression)
    ERE在在BRE基础上,增加了
    ( ) { } ? + |  等元字符
    
    • 转义符
    反斜杠 \
    反斜杠用于在元字符前添加,使其成为普通字符
    

基本的正则的表达式

测试的数据

[242-yuchao-class01 root ~]#cat -n t1.log 
I am teacher yuchao.
I teach linux,python!

I like english

My website is http://yuchaoit.cn
Our school site is https://apecome.com
My qq num is 877348180

Good good study , day day up!


my name is wu yan zu .

关于单引号、双引号

  • 没使用变量的话,请你都用单引号

grep与正则

接下来会以,过滤,查找文件内容,也就是结合grep来学习正则表达式

例如传入的pattern(模式是) ,我们可以统称你写的正则是模式

grep '关键字,模式,正则的表达式' 数据流
  • ^m,过滤以m开头的行
[root@linux-yzk ~]# grep '^m' t1.log 
my name is wu yan zu .
[root@linux-yzk ~]# 

# 显示行号 : 加上-n的参数
[root@linux-yzk ~]# grep '^m' t1.log -n
13:my name is wu yan zu .
[root@linux-yzk ~]# 

# -o 只显示grep找出来的结果,而不是那一行的所有的信息
[root@linux-yzk ~]# grep '^m' t1.log -n -o
13:m


^尖角符

语法
写于最左侧,如
^yu 逐行匹配,找到以yu开头的内容

结合grep用法,-i 忽略大小写,可以找到更多的数据匹配

找出以yu开头的行
[root@linux-yzk ~]# grep '^yu' t1.log -i  

找出以m或者M开头的行,且显示行号
[root@linux-yzk ~]# grep '^m' t1.log -ni
6:My website is http://yuchaoit.cn
8:My qq num is 877348180
13:my name is wu yan zu .
[root@linux-yzk ~]# 

只显示grep每次匹配到的结果,而不是匹配到的文本行数据

找出以my开头的行

[root@linux-yzk ~]# grep '^my' t1.log -nio
6:My
8:My
13:my
[root@linux-yzk ~]# 


匹配出qq那一行

grep 'qq'  t1.log

匹配行内容,且显示行号

找出包含i字符的行

[root@linux-yzk ~]# grep 'i' -n t1.log 
2:I teach linux,python!
4:I like english
6:My website is http://yuchaoit.cn
7:Our school site is https://apecome.com
8:My qq num is 877348180
13:my name is wu yan zu .
[root@linux-yzk ~]# 



找出以i开头的行
[root@linux-yzk ~]# grep '^i' t1.log -in 
1:I am teacher yuchao.
2:I teach linux,python!
4:I like english



找出以i开头的行,且只显示匹配内容
[root@linux-yzk ~]# grep '^my' t1.log -nio
6:My
8:My
13:my

$美元符 (匹配行尾)

语法

word$ 匹配以word结尾的行
匹配所有以字符n结尾的行

[root@linux-yzk ~]# grep 'n$' t1.log -ni
6:My website is http://yuchaoit.cn


匹配所有以.结尾的行  #一定要转义
[root@linux-yzk ~]# grep '\.$' t1.log -n
1:I am teacher yuchao.
13:my name is wu yan zu .
.

单、双引号区别

  • 单引号、所见即所得,可以用于匹配如标点符号,还原其本义。

  • 双引号、能够识别linux的特殊符号、或变量,需要借助转义符还原字符本义。

  • 当需要引号嵌套时,一般做法是,双引号,嵌套单引号。

^$ 匹配空行

^ 字符:
匹配以这个开头的行

$ 字符:
匹配以这个字符结尾的字符

^$ 字符:
表示以空的开头,以空结尾
表示空行
  • 找出文件的空行
[root@linux-yzk ~]# grep '^$' t1.log  -n 
3:
5:
9:
11:
12:
[root@linux-yzk ~]#

.点配符

. 匹配除了换行符以外所有的内容、字符+空格,除了换行符。

. 点处理空格

  • . 可以匹配到空格,以及任意字符

  • 以及拿不到空行

  • 但是点,不匹配换行符。(拿不到换行符,什么意思?)

# 测试的数据
cat -n t1.log
y
u
c
h

a o
  • 验证点和换行的操作
[root@linux-yzk ~]# grep '.' t1.log -ion
1:y
2:u
3:c
4:h
6:a
6: 
6:o
[root@linux-yzk ~]# 

. 匹配除换行符的所有字符

[root@linux-yzk ~]# grep '.' t1.log -n
1:y
2:u
3:c
4:h
6:a o

.代表任意一个字符

如 y. y..

[root@linux-yzk ~]# grep 'y.' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
4:My website is http://yuchaoit.cn
6:My qq num is 877348180
7:Good good study , day day up!
8:my name is wu yan zu .
[root@linux-yzk ~]# 


# 练习找出.ac正则的行
[root@linux-yzk ~]# grep '.ac' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
[root@linux-yzk ~]# 

.$匹配任意字符结尾

.表示任意一个字符
.$表示任意一个个字符的结尾

#拿到每一行结尾的字符

[root@linux-yzk ~]# grep '.$' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
6:My qq num is 877348180
7:Good good study , day day up!
8:my name is wu yan zu .

  • 拿到每一行结尾的字符
[root@linux-yzk ~]# grep '.$' -on t2.log 
1:.
2:!
3:h
4:n
5:m
6:0
7:!
8:.
[root@linux-yzk ~]# 

.和转义符

只想拿到每一行结尾的小数点,需要转义

grep '\.$' t2.log


[root@linux-yzk ~]# grep '\.$' t2.log
I am teacher yuchao.
my name is wu yan zu .
[root@linux-yzk ~]# 

\转义符

  • 转义符,让有特殊意义的字符,以原型的形式的本意。
\.
\$

转义符

空格,换行,tab

使用该网站,验证

https://deerchao.cn/tools/wegester/使用这个网址来测试换行符的匹配

换行符、制表符

\b 匹配单词边界,如我想从字符串中“This is Regex”匹配单独的单词 “is” 正则就要写成 “\bis\b”

hello world
helloworld


\n 匹配换行符 ,表示newline,向下移动一行,不会左右移动
\r 匹配回车符,表示return,回到当前行的最左边

在windows中,换行符号是 \r\n
linux中,换行符就是\n

linux中输入 enter键,表示\r \n


linux换行符是\n,表示\r+\n 换行且回车,换行且回到下一行的行首


windows换行符是\r\n,表示回车+换行

\t 匹配一个横向的制表符,等于tab键

*星号

  • 重复之前的字符0次或n次
[root@linux-yzk ~]# grep 'W*' t2.log 
I am teacher yuchao.
I teach linux,python!
I like english
My website is http://yuchaoit.cn
Our school site is https://apecome.com
My qq num is 877348180
Good good study , day day up!
my name is wu yan zu .
[root@linux-yzk ~]# 



[root@linux-yzk ~]# grep 'w*' t2.log  -no
4:w
8:w
11:wwwwwwwwwwwwwww
12:www
[root@linux-yzk ~]# 

.*符

.匹配任意一个字符

*重复前一个字符0次或N次

.* 找出任意内(这一行有东西,没东西)全给找出来,是*的作用对比. 和 .*就理解了

之找出字符的行

grep '.' t2.log

无论有无字符,都找出这行来
grep '.*' t2.log

图解点. 不匹配换行

首相,不匹配换行符,是因为. 的作用
.* 是重复前面这个字符的0次或者N次

重要的再次提醒.不处理换行

# 如下命令的证明

[root@linux-yzk ~]# grep '.*' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
6:My qq num is 877348180
7:Good good study , day day up!
8:my name is wu yan zu .
9:
10:
11:wwwwwwwwwwwwwww
12:www




[root@linux-yzk ~]# grep 'teach.*python' t2.log -n
2:I teach linux,python


###这是匹配前面是teach 中间是任意的字符 后面是python

^.*符

^m  以m开头

.* 任意内容

^.* 以任意内容开头
语法:
^.* 表示以任意的多个字母的开头行

1. 只找出i开头的行   ----参数i是忽略大小写
[root@linux-yzk ~]# grep '^i' t2.log -ni
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english


2.找出任意以字母i开头,以及匹配到后续所有数据
[root@linux-yzk ~]# grep '^.*i' t2.log  -in
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
6:My qq num is 877348180
8:my name is wu yan zu .

.*$符

以任意多个字符结尾

grep '.*$' t1.log
等于
grep '.*' t1.log 


[root@linux-yzk ~]# grep 'p.*$' t2.log  -n -i
2:I teach linux,python!
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
7:Good good study , day day up!
[root@linux-yzk ~]# 

[]中括号

  • [abc]
[abc] 匹配括号内的小写的a,b,c字符
[a-z]

[a-z]、 [A-Z] 、[a-zA-z]、[0-9]

[a-z]				匹配所有小写单个字母
[A-Z]				匹配所有单个大写字母
[a-zA-Z]		匹配所有的单个大小写字母
[0-9]				匹配所有单个数字
[a-zA-Z0-9]	匹配所有数字和字母

[a-z] 匹配小写字母

等于找出文件中所有的小写字母

[root@linux-yzk ~]# grep '[a-z]' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
6:My qq num is 877348180
7:Good good study , day day up!
8:my name is wu yan zu .
11:wwwwwwwwwwwwwww
12:www
[root@linux-yzk ~]# 

[A-Z]匹配大写的字母

[root@linux-yzk ~]# grep '[A-Z]' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
6:My qq num is 877348180
7:Good good study , day day up!
[root@linux-yzk ~]# 

[a-z0-9] 匹配小写字母和数字

[root@linux-yzk ~]# grep '[a-z0-9]' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
6:My qq num is 877348180
7:Good good study , day day up!
8:my name is wu yan zu .
11:wwwwwwwwwwwwwww
12:www
[root@linux-yzk ~]# 

[0-9A-Z] 匹配大写字母和数字

root@linux-yzk ~]# grep '[0-9A-Z]' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
6:My qq num is 877348180
7:Good good study , day day up!
[root@linux-yzk ~]# 

[^abc] 中括号取反

语法
语法

[^abc] 排除中括号里的a、b、c ,和单独的^符号,作用是不同的

[^a-z] 排除小写字母

[^a-z] 排除小写字母

[root@linux-yzk ~]# grep '[^a-z]' t2.log -n
1:I am teacher yuchao.
2:I teach linux,python!
3:I like english
4:My website is http://yuchaoit.cn
5:Our school site is https://apecome.com
6:My qq num is 877348180
7:Good good study , day day up!
8:my name is wu yan zu .
[root@linux-yzk ~]# 

{ } 花括号(扩展正则)

grep命令和扩展正则结合使用

grep '基本正则表达式'  t1.log

# 使用-E参数是最新扩展正则用法

grep -E '扩展正则表达式'  t1.log 

egrep '扩展正则表达式' t1.log

测试数据

I am teacher yuchao.
I teach linux,python!

I like english

My website is http://yuchaoit.cn
Our school site is https://apecome.com
My qq num is 877348180

aaaaaaaa

aaaaaple
Good good study , day day up!
my name is wu yan zu .

my name is wwwwwwwwwwwwwwwwwwwwwwwwu yifan.

[root@linux-yzk ~]# grep -E 'a{1,3}'  t1.log  -no
1:a
1:a
1:a
2:a
6:a
7:a
10:aaa
10:aaa
10:aa
12:aaa
12:aa
13:a
13:a
14:a
14:a
16:a
16:a
[root@linux-yzk ~]# 

a

a\{n,m\} 重复字符a,n到m次

a\{1,3\} 重复字符a,1到3次

# 建议用这个语法 ,使用-E参数

grep  -E 'a{1,3}' t1.log

实践

匹配数字8一次到3次

grep -E '[0-9]{1,8}' t1.log -n


[root@linux-yzk ~]# grep -E '[0-9]{1,8}' t1.log -n
8:My qq num is 877348180
10:my qq num is not  87777773333344444888811188880000
[root@linux-yzk ~]# 

每次最少找出2个8、最多3个8

grep -E '8{2,3}' t1.log 

[root@linux-yzk ~]# grep -E '8{2,3}' t1.log 
my qq num is not  87777773333344444888811188880000
[root@linux-yzk ~]# 

grep 默认不认识扩展正则 {}

grep默认不认识扩展正则{},识别不到它的特殊作用,因此只能用转义符,让他成为有意义的字符。

解决的办法

办法1
使用转义符 \{\}

办法2,让grep认识花括号,可以省去转义符
使用egrep命令
或者 grep -E 
  • 匹配数字8一次到3次
grep -E '8{1,3}'

[root@linux-yzk ~]# grep -E '8{2,3}' t1.log 
my qq num is not  87777773333344444888811188880000

a\{n,\}

重复a字符至少n次,可以用简写了

8至少出现2次
grep -E '8{2,}' t1.log

8至少出现1次
grep -E '8{1,}' t1.log

扩展正则表达式(ERE)

这样记忆就好

  • 基本正则表达式
    • 属于早期正则表达式,支持一些基本的功能
    • 与grep、sed命令结合使用
  • 扩展正则表达式
    • 后来添加的正则表达式
    • 和egrep、awk命令结合
    • 必须是grep -E 参数

+ 加号 ----->至少一个

语法

+ 
重复前一个字符1次或多次


注意和*的区别,*是0次或多次,找不到的那一行,也会显示出来

匹配一次或者多次0,没有0的行是不会显示的

0+

要求

每次找出一个、或者多个数字零
找出存在至少一次0的行
grep '0+'  t1.log


[242-yuchao-class01 root ~]#grep -E  '0+'  t1.log -n
8:My qq num is 877348180
10:my qq num is not  87777773333344444888811188880000

*和+的区别

*和+的区别

例如,我们来找到字母o,看如下2个写法

go*d和go+d和go?d区别

准备测试数据

[root@yuchao-tx-server test]# cat god.log
I am God, I need you to good good study and day day up, otherwise I will send you to see Gd,oh sorry, gooooooooood!
posted @ 2025-03-14 14:59  国家一级冲浪yzk  阅读(29)  评论(0)    收藏  举报