正则表达式


       相信我们都见过类似于这样的寻人启示吧,我们要想在茫茫人海中寻找某个人,就相当于从某些信息筛选出某个有用信息,上面的描述中有具体的描述,比如高龄88,失踪前的穿衣打扮,但也有模糊的描述,比如体重略胖,步履略蹒跚等,这跟我们在一堆信息中要筛选出我们需要的信息一样,有时我们知道具体要查找的内容,而有时只知道大概,类似于这样的筛选我们要借助什么完成呢?这就需要深入了解一下我们今天所提到的——正则表达式

什么是正则表达式

       百度百科解释戳这里点击打开链接,在这里简单总结一下,正则表达式是用于描述一组字符串特征的模式,用来匹配特定的字符串。通过特殊字符+普通字符来进行模式描述,从而达到文本匹配目的的工具。

正则表达式的分类

(1)基本的正则表达式(Basic Regular Expression又叫Basic RegEx,简称BREs)

(2)扩展的正则表达式(Extended Regular Expression又叫Extended RegEx简称EREs)

(3)Perl的正则表达式(Perl Regular Expression又叫Perl RegEx简称PREs)

正则表达式的应用场景

(1)验证:表单提交时,进行用户名密码验证

(2)查找:从大量信息中快速提取指定内容;

(3)替换:将指定格式的文本,进行正则匹配查找,找到之后进行特定替换(vim文本替换)

具体测试正则表达式我们需要用到grep模式匹配命令,我们先来了解一下,在实际应用中我们也可以直接用工具验证点击打开链接

1、grep命令用于打印输出文本中匹配的模式串,它使用正则表达式作为模式匹配的条件

grep支持以下三种正则表达式引擎,分别用三个参数指定


grep命令的常用参数解析


注:

(1)grep指令后不跟任何参数,表示要使用BRE

(2)正则表达式的Extended规范和Basic规范的不同:

  • 在Basic规范下,有些字符?+{}|()应解释为普通字符,要表示特殊字符含义需要加\转义
  • 在Extended规范下,?+{}|()应该被理解为特殊含义,要取其字面值,也要对其进行\转义
  • grep命令默认支持基础正则表达式,而egrep默认支持扩展正则表达式,因此常用egrep代替grep -E
  • fgrep表示快速匹配,不支持正则表达式,没有转义的概念,会对PATTERN中的所有字符进行匹配

正则表达式的基本要素

(1)字符类

(2)数量限定符

(3)位置限定符

(4)特殊符号

下面我们分别来讨论这四个要素

1、字符类


具体实例演示:



2、数量限定符


[root@localhost reg]# echo "lluying" | grep -E --color 'l?'
lluying
[root@localhost reg]# echo "llluying" | grep -E --color 'l?'
llluying
[root@localhost reg]# echo "lying" | grep -E --color 'l?'
lying
[root@localhost reg]# echo "uying" | grep -E --color 'l?'
uying
[root@localhost reg]# echo $?
0    //匹配成功了,grep是贪心匹配
[root@localhost reg]# echo "uying" | grep -E --color 'l+'
[root@localhost reg]# echo "uying" | grep -E --color 'l+'
[root@localhost reg]# echo $?
1    //匹配不成功,至少一次
[root@localhost reg]# echo "llluying" | grep -E --color 'l+'
llluying
[root@localhost reg]# echo "luying" | grep -E --color 'l+'
luying
[root@localhost reg]# echo "luying" | grep -E --color 'l*'
luying
[root@localhost reg]# echo "lurteluying" | grep -E --color 'l*'
lurteluying
[root@localhost reg]# echo "llllllurteluying" | grep -E --color 'l*'
llllllurteluying
[root@localhost reg]# echo "haiuying" | grep -E --color 'l*'
haiuying
[root@localhost reg]# echo $?
0
[root@localhost reg]# echo "lurteluying" | grep -E --color 'l{1}'
lurteluying
[root@localhost reg]# echo "lurteluying" | grep -E --color 'l{2}'
[root@localhost reg]# echo "lurtelluying" | grep -E --color 'l{2}'
lurtelluying
[root@localhost reg]# echo "lurtelluying" | grep -E --color 'l{3}'
[root@localhost reg]# echo "lllurtelluying" | grep -E --color 'l{3}'
lllurtelluying
[root@localhost reg]# echo "lllurtellluying" | grep -E --color 'l{3}'
lllurtellluying
[root@localhost reg]# echo "lllurtellllluying" | grep -E --color 'l{3}'
lllurtellllluying
[root@localhost reg]# echo "lllurtellllluying" | grep -E --color 'l{3,}'
lllurtellllluying
[root@localhost reg]# echo "lllurtelluying" | grep -E --color 'l{3,}'
lllurtelluying
[root@localhost reg]# echo "lurtelluying" | grep -E --color 'l{3,}'
[root@localhost reg]# echo "lurtelluying" | grep -E --color 'l{,3}'
[root@localhost reg]# echo "lurtellluying" | grep -E --color 'l{,3}'
[root@localhost reg]# echo $?
1    //不支持,在相关文档中并未出现,应该是错误或者废弃的用法
[root@localhost reg]# echo "lurtellluying" | grep -E --color 'l{2,4}'
lurtellluying
[root@localhost reg]# echo "lurteluying" | grep -E --color 'l{2,4}'
[root@localhost reg]# echo $?
1
[root@localhost reg]# echo "lurtelluying" | grep -E --color 'l{2,4}'
lurtelluying
[root@localhost reg]# echo "lurtelllllluying" | grep -E --color 'l{2,4}'
lurtelllllluying

3、位置限定符

字符含义举例
^匹配行首的位置^luying匹配位于一行开头的luying
$匹配行末的位置;$匹配位于一行结尾的;号,^$匹配空行

\<

匹配单词开头的位置\<th匹配…this,但不匹配ethernet、tenth
\>匹配单词结尾的位置p\>匹配leap…,但不匹配parent、sleepy
\b匹配单词开头或结尾的位置\bat\b匹配…at…,但不匹配cat、atend、batch等
\B匹配非单词开头和结尾的位置\Bat\B匹配battery,但不匹配…attend、bat…

使用用例

[root@localhost reg]# echo "hai ehai hail ahail hai" | grep -E --color '^hai'
hai ehai hail ahail hai
[root@localhost reg]# echo "hai ehai hail ahail hai" | grep -E --color 'hai$'
hai ehai hail ahail hai
[root@localhost reg]# echo "hai ehai hail ahailhai" | grep -E --color 'hai$'
hai ehai hail ahailhai
[root@localhost reg]# echo "hai ehai hai ahailhai" | grep -E --color 'hai$'
hai ehai hai ahailhai
[root@localhost reg]# echo "hai ehai hai ahailhai" | grep -E --color '/bhai/b'
[root@localhost reg]# echo "hai ehai hai ahailhai" | grep -E --color '^hai$'
[root@localhost reg]# echo "hai" | grep -E --color '^hai$'
hai
[root@localhost reg]# echo "hai ehai hai ahailhai" | grep -E --color '\>hai'
[root@localhost reg]# echo "hai ehai hai ahailhai" | grep -E --color '\<hai'
hai ehai hai ahailhai
[root@localhost reg]# echo "hai ehai hai hailhai" | grep -E --color '\<hai'
hai ehai hai hailhai
[root@localhost reg]# echo "hai ehai hai ahailhai" | grep -E --color '\>hai'
[root@localhost reg]# echo $?
1
[root@localhost reg]# echo "haieho ehai hai ahailhai" | grep -E --color '\>hai'
[root@localhost reg]# echo "haieho hai hai ahailhai" | grep -E --color '\>hai'
[root@localhost reg]# echo "haieho haihai hai ahailhai" | grep -E --color '\>hai'
[root@localhost reg]# echo "haieho haihai haielo ahailhai" | grep -E --color '\>hai'
[root@localhost reg]# echo "haieho haihai haielo hailhai" | grep -E --color '\>hai'
[root@localhost reg]# echo "hai ehai hai hailhai" | grep -E --color '\<hai'
hai ehai hai hailhai
[root@localhost reg]# echo "hello ahello hellow hello" | grep -E --color '^hello'
hello ahello hellow hello
[root@localhost reg]# echo "hello ahello hellow hello" | grep -E --color 'hello$'
hello ahello hellow hello
[root@localhost reg]# echo "hello ahello hellow hello" | grep -E --color '^hello$'
[root@localhost reg]# echo $?
1
[root@localhost reg]# echo "hello" | grep -E --color '^hello$'
hello
[root@localhost reg]# echo "hello ahello helloq ahelloy hello" | grep -E --color '\>hello'
[root@localhost reg]# echo $?
1
[root@localhost reg]# echo "hello ahello helloq ahelloy hello" | grep -E --color 'hello\>'
hello ahello helloq ahelloy hello
[root@localhost reg]# echo "hello ahello helloq ahelloy hello" | grep -E --color 'hello\<'
[root@localhost reg]# echo "hello ahello helloq ahelloy hello" | grep -E --color '\<hello\>'
hello ahello helloq ahelloy hello
[root@localhost reg]# echo "hello ahello helloq ahelloy hello" | grep -E --color '\bhello'
hello ahello helloq ahelloy hello
[root@localhost reg]# echo "hello ahello helloq ahelloy hello" | grep -E --color '\bhello\b'
hello ahello helloq ahelloy hello
[root@localhost reg]# echo "hello ahello helloq ahelloy hello" | grep -E --color '\Bhello'
hello ahello helloq ahelloy hello
[root@localhost reg]# echo "hello ahello helloq ahelloy hello" | grep -E --color '\Bhello\B'
hello ahello helloq ahelloy hello       //其中 \b 用来限定是目标串中是否有以指定字符串开头的单词,我们称之为词界。  \B 称之为非词界

4、特殊符号

字符含义举例
\

转义字符,普通字符转义为特殊字符,特殊字符转义

为普通字符

普通字符<写成\<表示单词开头的位置,特殊字符.写成\.

以及\写成\\就当作普通字符来匹配

()

将正则表达式的一部分括起来组成一个单元,可以对整

个单元使用数量限定符

([0-9]{1,3}\.){3}[0-9]{1,3}匹配IP地址
|连接两个子表达式,表示或的关系n(o|either)匹配no或neither

使用用例

[root@localhost reg]# echo "abcabcabcdef" | grep -E --color '(abc){3}'
abcabcabcdef  //用()表示将包含的内容作为一个整体,作为一个单元,进而可以用数量限定符来进行限定
[root@localhost reg]# echo "abcabcabcabcdef" | grep -E --color '(abc){3}'
abcabcabcabcdef
[root@localhost reg]# echo "abcabcabcabcdef" | grep  --color '(abc){3}' //去掉-E选项  表明是基础正则表达式
[root@localhost reg]# echo $?
1     //并没有正常匹配
[root@localhost reg]# echo "abcabcabcabcdef" | grep  --color '\(abc\)\{3\}'  //加\转义
abcabcabcabcdef
[root@localhost reg]# echo "ad{}()+|?cd" | grep --color '{}()+|?'
ad{}()+|?cd
[root@localhost reg]# echo "ad{}()+|?cd" | grep -E --color '{}()+|?'
ad{}()+|?cd
[root@localhost reg]# echo "ad{}()+|?cd" | grep -E --color '\{\}\(\)\+\|\?' //在Extended规范下, ?+{}|() 应该被理解成特殊含义,要取其字面值,也要对其进行 \ 转义
ad{}()+|?cd
[root@localhost reg]# echo "ad{}()+|?cd" | grep -E --color 'ad'
ad{}()+|?cd
[root@localhost reg]# echo "ad{}()+|?cd" | grep -E --color 'cd'
ad{}()+|?cd
[root@localhost reg]# echo "ad{}()+|?cd" | grep -E --color 'ad|cd'  // |用来级联多个条件,只要有任意一个匹配,即可匹配,表示或者关系,我们称之为析取符,再次强调, | 可以用
来级联多个条件
ad{}()+|?cd

其他常用通用字符集及其替换

符号替换正则匹配
\d[0-9]数字字符
\D[^0-9]非数字字符
\w[a-zA-Z0-9_]数字字母下划线
\W[^\w]非数字字母下划线
\s[_\r\t\n\f]表格,换行等空白区域
\S[^\s]非空白区域

使用用例


练习:

[root@localhost reg]# cat file4   //搜索手机号码
45625882214
15268654939
18700586318
1110
456.3786358
49822566321
8976255a
123456789h
18700586318g
t13434741456
[root@localhost reg]# grep -E --color '1[34578][0-9]{9}' file4  
15268654939
18700586318
18700586318g
t13434741456
[root@localhost reg]# grep -E --color '^1[34578][0-9]{9}$' file4
15268654939
18700586318
[root@localhost reg]# echo 1234 | grep -P --color '^[1-9]\d*$'  //非零堆的正整数
1234
[root@localhost reg]# echo a1234 | grep -P --color '^[1-9]\d*$'
[root@localhost reg]# echo $?
1
[root@localhost reg]# echo "1234.56" | grep -E --color '^[1-9][0-9]*\.[0-9]{1,2}$'  //非零开头的最多带两位小数的数字
1234.56
[root@localhost reg]# echo "1234.566" | grep -E --color '^[1-9][0-9]*\.[0-9]{1,2}$'
[root@localhost reg]# echo "1234.566 123.54" | grep -E --color '^[1-9][0-9]*\.[0-9]{1,2}$'
[root@localhost reg]# echo $?
1
[root@localhost reg]# echo "abcde345ioAEFHRH" | grep -E --color '^[0-9a-zA-Z]+$'  //由数字和26个英文字母组成的字符串
abcde345ioAEFHRH

配合正则表达式使用的工具介绍

sed

  • sed是一种流编辑器,是文本处理中非常重要的工具,主要用来自动编辑一个或多个文件,简化对文件的反复操作,编写转换程序等;
  • 处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”;
  • 接着用sed命令处理缓冲区中的内容,处理完成之后,把缓冲区的内容送往屏幕;
  • 接着处理下一行,这样不断重复,直到文件末尾;
  • sed默认按照基础正则规则进行匹配;
  • 文件内容并没有改变,除非你使用了重定向存储输出;
  • 注意:sed命令:先正则匹配后动作

1、基本使用方法:

  • /pattern/p:打印匹配pattern的行
[root@localhost reg]# cat file
aaaaaaa
bbbbbbb
ccccccc
ddddddd
ddddddd
[root@localhost reg]# sed '/^.*printf.*;$/d' file3
#include<stdio.h>
int main()
{
	return 0;
}
[root@localhost reg]# cat file3
#include<stdio.h>
int main()
{
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	return 0;
}
hhhhhhh
fffffff
[root@localhost reg]# sed '/^a\+$/p' file
aaaaaaa
aaaaaaa
bbbbbbb //sed是把待处理文件的内容联通处理结果一起输出到标准输出的
ccccccc //因此p命令处理把文件内内容打印出来以外还额外打印了一遍pattern的行
ddddddd
ddddddd
hhhhhhh
fffffff
[root@localhost reg]# sed -n '/^a\+$/p' file //要想只输出处理结果,应加上-n选项(相当于grep命令)
aaaaaaa
  • /pattern/d:删除匹配pattern的行
[root@localhost reg]# sed '/^.*printf.*;$/d' file3
#include<stdio.h>
int main()
{
	return 0;
}
[root@localhost reg]# cat file3
#include<stdio.h>
int main()
{
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	return 0;
}
可以看出,sed命令不会修改原文件,删除命令只表示行不打印输出,而不是从原文件中删去,如果要影响原文件,要使用-i选项
[root@localhost reg]# sed -i '/^.*printf.*;$/d' file3
[root@localhost reg]# cat file3
#include<stdio.h>
int main()
{
	return 0;
}
  • /pattern/s/pattern1/pattern2/:查找符合pattern的行,将该行第一个匹配pattern1的字符串替换为pattern2
[root@localhost zhengze]# cat file1
#include<stdio.h>
int main()
{
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	return 0;
}
[root@localhost zhengze]# sed '/^.*printf(.*);$/s/^/\/\//' file1
#include<stdio.h>
int main()
{
//	printf("hai nihao\n");
//	printf("hai nihao\n");
//	printf("hai nihao\n");
//	printf("hai nihao\n");
//	printf("hai nihao\n");
	return 0;
}
  • /pattern/s/pattern1/pattern2/g:查找符合pattern的行,将该行所有匹配pattern1的字符串替换为pattern2
[root@localhost zhengze]# cat file
aaaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
ccccccccccccccc
ccccccccccccccc
eeeeeeeeeeeeeee
[root@localhost zhengze]# sed '/^a\+/p' file
aaaaaaaaaaaaaaa
aaaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
ccccccccccccccc
ccccccccccccccc
eeeeeeeeeeeeeee
[root@localhost zhengze]# sed '/^a\+/s/a/#a#/' file
#a#aaaaaaaaaaaaaa
bbbbbbbbbbbbbbb
ccccccccccccccc
ccccccccccccccc
eeeeeeeeeeeeeee
[root@localhost zhengze]# sed '/^a\+/s/a/#a#/g' file
#a##a##a##a##a##a##a##a##a##a##a##a##a##a##a#
bbbbbbbbbbbbbbb
ccccccccccccccc
ccccccccccccccc
eeeeeeeeeeeeeee
[root@localhost zhengze]# cat file1
#include<stdio.h>
int main()
{
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	printf("hai nihao\n");
	return 0;
}
[root@localhost zhengze]# sed '/^a\+/s/a/#&#/g' file //已匹配字符串标记&,可以表示pattern1之后的所有字符
#a##a##a##a##a##a##a##a##a##a##a##a##a##a##a#
bbbbbbbbbbbbbbb
ccccccccccccccc
ccccccccccccccc
eeeeeeeeeeeeeee
[root@localhost zhengze]# echo "this is luying"
this is luying
[root@localhost zhengze]# echo "this is luying" | sed 's/\w\+/[&]/g'
[this] [is] [luying]

  • 子串匹配标记\1\2…\n
[root@localhost zhengze]# echo "hai dalao 456"
hai dalao 456
[root@localhost zhengze]# echo "hai dalao 456" | sed 's/\([0-9]\)\([0-9]\)\([0-9]\)/\3\2\1/'
hai dalao 654
\(……\)用于匹配子串,对于匹配到的第一个子串就标记为\1,依次类推匹配到的第二个结果就是\2,通过堆标签进行重组,从而完成数据逆置
  • 定址
  • ---->用于决定哪些行进行编辑,地址的形式可以是数字,正则表达式或二者的结合,如果没有指定地址,sed将处理所有行
  • [root@localhost zhengze]# for i in {a..h};do echo $i;done >> file2
    [root@localhost zhengze]# cat file2
    a
    b
    c
    d
    e
    f
    g
    h
    [root@localhost zhengze]# sed -n '3,5p' file2  //打印3-5行的信息
    c
    d
    e
    [root@localhost zhengze]# sed '3,5d' file2   //删除3-5行
    a
    b
    f
    g
    h
    [root@localhost zhengze]# sed -n '/^f/,/^h/p' file2 //打印以f开头行和以h开头行之间的内容
    f
    g
    h
    [root@localhost zhengze]# cat file2
    a
    b
    c
    d
    e
    f
    g
    h
    [root@localhost zhengze]# sed  '/^f/,/^h/d' file2  //删除以f开头和以h开头行之间的内容
    a
    b
    c
    d
    e
    [root@localhost zhengze]# sed -n '/^a/,3p' file2  //打印以a开头到第3行的内容
    a
    b
    c
    [root@localhost zhengze]# sed '/^a/,3d' file2 //删除以a开头到第三行的内容
    d
    e
    f
    g
    h
    [root@localhost zhengze]# echo $?
    0            //sed与grep不同,不管是否找到指定的模式,他的退出状态都是0,只有当命令存在语法错误是退出状态才不是0

2、sed的模式空间和保持空间的区别

  • 模式空间:可以想成工程里面的流水线,数据直接在它上面进行处理
  • 保持空间:可以想象成仓库,我们在进行数据处理的时候,作为数据的暂存区域
  • 正常情况下,如果不显示使用某些高级命令,保持空间不会使用到

3、sed的高级命令

  • g:将保持空间中的内容拷贝到模式空间中,原来的模式空间里的内容被清空
  • G:将保持空间中的内容追加到模式空间\n后
  • h:将模式空间中的内容拷贝到保持空间中,原来的保持空间的内容被清空
  • H:将模式空间的内容追加到保持空间\n后
  • d:删除pattern中的所有行,并读入下一新行到pattern中
  • D:删除multiline pattern中的每一行,不读入下一行
  • x:交换保持空间和模式空间的内容
  • N:将下一行添加到模式空间中
  • n:读取下一行到模式空间中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值