正则表达式的作用
正则表达式是一种字符模式,用于在查找过程中匹配指定的字符。
正则当中名词解释
-
元字符
指那些在正则表达式中具有特殊意义的专用字符,如:点(.) 星(*) 问号(?)等
-
前导字符
位于元字符前面的字符. niu* zhu?
第一类正则表达式
正则中普通常用的元字符
元字符 | 作用 | 例子 |
---|---|---|
. | 匹配除了换行符以外的任意单个字符 | |
* | 前导字符出现0次或连续多次 | |
.* | 任意长度字符 | a.* |
^ | 以…开头 | ^root |
$ | (以…结尾) bash$ | |
^$ | 空行 | |
[ ] | 匹配括号里任意单个字符或一组单个字符 [abc] | |
[^ ] | 匹配不包含括号里任一单个字符或一组单个字符 abc | [^abc] |
^[] | 匹配以括号里任意单个字符或一组单个字符开头 | ^[abc] |
^[^ ] | 匹配不以括号里任意单个字符或一组单个字符开头 | ^[^abc] |
案例
示例文本
# cat 1.txt
ggle
gogle
google
gooogle
goooooogle
gooooooogle
taobao.com
taotaobaobao.com
jingdong.com
dingdingdongdong.com
10.1.1.1
Adfjd8789JHfdsdf/
a87fdjfkdLKJK
7kdjfd989KJK;
bSKJjkksdjf878.
cidufKJHJ6576,
hello world
helloworld yourself
正则应用
.
匹配除了换行符以外的任意单个字符
*
前导符出现0次或多次
.*
所有
^
以什么开头
$
以什么结尾
^$
空行 -v是取反
-n
是显示匹配的行号
[]
匹配括号里任意单个字符或一组单个字符
^[]
开头 ^[^]
括号里取反的开头
括号里取反
在这里面 !
不是取反
正则中其他常用元字符
元字符 | 作用 | 例子 |
---|---|---|
< | 取单词的头 | |
> | 取单词的尾 | |
< > | 精确匹配 | |
{n} | 匹配前导字符连续出现n次 | |
{n,} | 匹配前导字符至少出现n次 | |
{n,m} | 匹配前导字符出现n次与m次之间 | |
( ) | 保存被匹配的字符 | |
\d | 匹配数字(grep -P) | [0-9] |
\w | 匹配字母数字下划线(grep -P) | [a-zA-Z0-9_] |
\s | 匹配空格、制表符、换页符(grep -P) | [\t\r\n] |
案例
\<
取单词的头
\>
取单词的尾
\<\>
精确匹配
\{\}
匹配前导符连续出现n次
{n,}
至少出现n
次
{2,4}出现2到4次
匹配ip
()保存被匹配的字符
先写一个测试文件
[root@maomao pancheng]# cat test.txt
hello world
helloworld yourself
yourself helloworld
[root@maomao pancheng]# sed -r 's/hello(world) your(self)/hi\1my\2/' test.txt
hello world
hiworldmyself
yourself helloworld
\d
就是匹配数字 但是grep要加-P
\w
就是匹配字母数字下划线[a-zA-Z_]
扩展类正则常用元字符
-
grep,必须加 -E 或者 egrep
-
sed,必须加 -r
扩展元字符 | 作用 | 例子 |
---|---|---|
+ | 匹配一个或多个前导字符 | bo+ 匹配boo、 bo |
? | 匹配零个或一个前导字符 | bo? 匹配b、 bo |
| | 匹配 | 左边或者右边的字符 | a|b 匹配a或者b |
() | 组字符(看成整体) | (my|your)self : 表示匹配myself或匹配yourself |
{n} | 前导字符重复n次 | |
{n,} | 前导字符重复至少n次 | |
{n,m} | 前导字符重复n到m次 |
案例
+
匹配一个或多个前导字符
?
匹配0次或1次前导字符
.?
出现0次或一次任意字符
|
是或 匹配a或b
()
组字符 看成一个整体 (my|your)self;匹配myself或者yourself
第二类正则
表达式 | 作用 | 例子 |
---|---|---|
[:alnum:] | 字母与数字字符 | [[:alnum:]]+ |
[:alpha:] | 字母字符(包括大小写字母) | [[:alpha:]]{4} |
[:blank:] | 空格与制表符 | [[:blank:]]* |
[:digit:] | 数字 | [[:digit:]]? |
[:lower:] | 小写字母 | [[:lower:]]{4,} |
[:upper:] | 大写字母 | [[:upper:]]+ |
[:punct:] | 标点符号 | [[:punct:]] |
[:space:] | 包括换行符,回车等在内的所有空白 | [[:space:]]+ |
应用案例
过滤ip地址
[root@maomao ~]# egrep '[1-9][0-9]{0,2}(\.[0-9]{1,3}){3}' /etc/sysconfig/network-scripts/ifcfg-en
s33IPADDR=192.168.188.158
NETMASK=255.255.255.0
GATEWAY=192.168.188.2
DNS1=8.8.8.8
过滤邮箱
[root@maomao ~]# egrep '[a-z0-9_]+@[a-z0-9]+\.[a-z]+' email.txt
123456789@qq.com
maomao2zhuzhu@hotmail.com
maomao@mail.com
一个简单的过滤数字脚本
#!/bin/bash
read -p "输入:" n
if [[ "$n" =~ ^[0-9]+$ ]];then
echo "number."
else
echo "error"
fi
# 或者
#!/bin/bash
read -p "输入:" n
echo $n |egrep '^[0-9]+$' &>/dev/null
if [ $? -eq 0 ];then
echo "$n is number"
else
echo "error"
fi
过滤注释行和空行
# 先写一个测试txt
[root@maomao ~]# cat email.txt
maomao@mail.com
#asfdafqw
#wqfwqfq
#1612521
124#235
# 过滤所有注释行
[root@maomao ~]# egrep $'^#| #|\t' email.txt
#asfdafqw
#wqfwqfq
#1612521
[root@maomao ~]# egrep -v $'^#| #|\t' email.txt
maomao@mail.com
124#235
# 过滤空行
[root@maomao ~]# egrep -r '^$' email.txt
过滤ip地址脚本
#!/bin/bash
file="/etc/sysconfig/network-scripts/ifcfg-ens33"
while :
do
read -p "请输入ip:" ip
#echo $ip | egrep '[1-9][0-9]{0,2}(\.[0-9]{1,3}){3}'
echo $ip | egrep "^(([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-4])\.){3}([1-9]|[1-9][0-9]|1[0-9][0
-9]|2[0-4][0-9]|25[0-4])\b" &> /dev/null if [ $? -eq 0 ];then
echo "$ip"
exit
else
echo "错误"
fi
done
总结一下
- 我要找什么?
找数字 [0-9]
找字母 [a-zA-Z]
找标点符号 [[:punct:]] - 我要如何找?看心情找
以什么为首 ^key
以什么结尾 key$
包含什么或不包含什么 [abc] ^[abc] [^abc] ^[^abc] - 我要找多少呀?
找前导字符出现0次或连续多次 ab*
找任意单个(一次)字符 ab.
找任意字符 ab.*
找前导字符连续出现几次 {n} {n,m} {n,}
找前导字符出现1次或多次 go+
找前到字符出现0次或1次 go?