Shell编程中的正则表达式

前言

       在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说,正则表达式就是记录文本规则的代码。

一、正则表达式

 1.正则表达式概述

  正则表达式通常用于判断语句中,用来检查某一字符串是否满足某一格式。

  正则表达式是由普通字符元字符组成。普通字符包括小写字母、数字、标点符号及一些其他符号。元字符是指在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。

 2.正则表达式的分类

  正则表达式根据从POSIX BRE或者POSIX ERE标准可以分为基本正则表达式和扩展正则表达式。

 基本正则表达式

支持的工具:grep、egrep、sed、 awk,注意grep要配合-E或者-P使用。

元字符含义及用法
\转义字符,用于取消特殊符号的含义,例: \! 、 \n 、 \$等
^匹配字符串开始的位置,例:^a、^the、^#、^[a-z]
$匹配字符串结束的位置,例: word$、^$匹配空行
.匹配除`\n`之外的任意的一个字符,例: go.d、g..d。如果想要匹配包含\\n字符可以使用 [.\n]
*匹配前面子表达式0次或者多次,例: `goo*d`、 `go.*d`
[list]匹配list列表中的一个字符,例: `go[ola]d`,`[abc]`、`[a-z]`、`[a-z0-9]`、`[0-9]`匹配任意一位数字
[^list]匹配任意非list列表中的一个字符,例:`[^0-9]`、`[^A-Z0-9]`、`[^a-z]`匹配任意一位非小写字母
\{n\}匹配前面的子表达式n次,例: `go\{2\}d`、 `[0-9]\{2\}`匹配两位数字
\{n,\}匹配前面的子表达式不少于n次,例: `gol{2,l}d`、`[0-9]\{2,\}`匹配两位及两位以上数字
\{n,m\}匹配前面的子表达式n到m次,例 : `go\{2,3\}d`、`[0-9]\{2,3\}`匹配两位到三位数字。
\w匹配包括下划线的任何单词字符。
\W匹配任何非单词字符。等价于`[^A-Za-z0-9_]`。
\d匹配一个数字字符。
\D匹配一个非数字字符。等价于`[^0-9]`。
\s空白符。
\S非空白符。

 扩展正则表达式

支持的工具:`egrep`、`awk`,注意:使用`grep`要配合`-E`或者`-P`使用,`sed`要配合`-r`使用。

元字符含义及用法
+匹配前面子表达式1次以上,例: go+d,将匹配至少一个o,如god、good、goood等
匹配前面子表达式0次或者1次,例: `go?d`,将匹配`gd`或`god`
()将括号中的字符串作为一个整体,例1: `g(oo)+d`,将匹配`oo`整体1次以上,如`good`、`gooood`等
|以或的方式匹配字符串,例:`g(oo|la)d`,将匹配`good`或者 `glad`

3.正则表达式的使用

* ^ $的用法

[root@localhost ~]# cat testfile6 
gd
god
good
goood
goooadcd
gooooooodddd
abccba
abccba
abccba123
oooogooood
ooooogd
gold
goad
[root@localhost ~]# grep goo*d testfile6
#查询一串字符中有goo*d字样,且o有0个或多个,此字符串可以不在开头或结尾   
good
goood
gooooooodddd
oooogooood
[root@localhost ~]# grep "^goo*d$" testfile6 
#查询以g开头d结尾,中间的o有0个或多个
god
good
goood

[] \[^\]的用法

[root@localhost ~]# grep "go[ola]d" testfile6 
#查询一个字符,其中有一段以go开头d结尾,中间的o、l、a这几种字符中的一种
good
gold
goad
[root@localhost ~]# grep "go[ola]*d" testfile6 
#查询一个字符,其中有一段以go开头d结尾,中间的o、l、a这几种字符中的一个或多个
god
good
goood
goooadcd
gooooooodddd
oooogooood
gold
goad
[root@localhost ~]# grep "^[^a-g]" testfile6 
#匹配除了a-g开头的字符
oooogooood
ooooogd

\\{n\\} \\{n,\\} 的用法

[root@localhost ~]# grep "go\{2\}d" testfile6 
#匹配good字符,其中\{2\}只会匹配前面的o两次
good
[root@localhost ~]# 
[root@localhost ~]# grep "go\{2,\}d" testfile6
#匹配go..d,其中o至少2次及以上
good
goood
gooooooodddd
oooogooood

 4.常见例题

 电话例题

找出区号025开头的号码,且号码与区号间可以是空格、-、没有,号码必须是5或者8开头的八位数。

[root@localhost ~]# cat iphone.sh 
02588888888
025-55555555555
025 112345678
025 54321678ada
025-abc88888
025-58432109
028-85461913
0251-52765421

解题思路

先将电话拆分为3段,第一段找出区号,第二段筛选出号码与区号之间的分隔符,第三段号码后几位。区号025开头。^是以什么为开头,用()将025作为一个整体
 

^(025)

号码与区号间可以是空格、-、没有。将题目要求的空格和-写入\[\],由于?是前面的子表达式0次或1次,0次就符合题目要求的没有

 [ -]?

号码必须是5或者8开头的八位数。用\[\]确认是5或8数字开头的号码,然后再匹配0-9的7位数结尾的数
 

[58][0-9]{7}$

总体输出如下:

[root@localhost ~]# egrep "^(025)[ -]?[58][0-9]{7}$" iphone.sh 
egrep: warning: egrep is obsolescent; using grep -E
02588888888
025-58432109

 电子邮箱例题

根据 `用户名@子域名.[二级域名].顶级域` 格式找出符合要求的电子邮箱

[root@localhost ~]# cat mail.sh
zhangsan123@qq.com
li si@163.com
wang@wu@sina.com
zhao liu@126.com
qianqi@sina.com.cn

解题思路

将邮箱拆分为三段,第一段用户名,第二段子域名二级域,第三段顶级域

用户名@:长度要求在6-18位,任意大小写英文,任意数字,除了@符号和空格以外的其它任意符号字符,开头只能是 \_ 或者字母

^([a-zA-Z_][^@ ]{5,17})@

子域名.\[二级域名\]:长度任意,符号只能包含 - \_ .

[a-zA-Z0-9\_\-\.]+(\.[a-zA-Z0-9\_\-\.]+)?

.顶级域名: 长度在2-5,任意大小写英文

\.([a-zA-Z]{2,5})$

总体输出如下:

[root@localhost ~]# grep -E "^([a-zA-Z_][^@ ]{5,17})@[a-zA-Z0-9\_\-\.]+(\.[a-zA-Z0-9\_\.]+)?\.([a-zA-Z]{2,5})$" mail.sh
zhangsan123@qq.com
qianqi@sina.com.cn

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值