正则表达式:
正则表达式中的元字符:
.: 单个任意字符(除换行外)
\d: 数字0-9 [0-9]
\w: ascii: 匹配的是[a-zA-Z0-9_], unicode: 匹配大部分unicode字符: 中英文数字还有_
\s: 空白符:空格,制表符
\S: 对\s取补集: 非空字符
[abc]: 匹配a或者b或者c
[^abc]: 对abc取补集: 匹配单个除abc外的字符
量词:代表的数量
贪婪模式:
*: *之前的表达式重复0次到任意多次,尽可能多的去匹配
+:+之前的表达式重复1次到任意多次,尽可能多的去匹配
?:?之前的表达式重复0次到1次,尽可能多的去匹配
{n}: 重复n次
{n,m}: 最少重复n次,最多重复m次: 尽可能多的去匹配
{n,}
{,m}
非贪婪模式:
*?: *之前的表达式重复0次到任意多次,尽可能少的去匹配
+?:+之前的表达式重复1次到任意多次,尽可能少的去匹配
??:?之前的表达式重复0次到1次,尽可能少的去匹配
{n}?
{n,m}?
{,m}?
{n,}?
grep -P: Perl: 正则表达式支持比较全面
grep -e: 基本正则表达式
-E: 扩展正则表达式
^:代表...开始
$:代表...结束
|:A|B: 匹配A或者匹配B
(): 分组的概念:用()括起来的就是组,()不参加匹配
[root@rocky 20220828]# echo "123456123"| grep -e "\(123\)456\1"
123456123
[root@rocky 20220828]# echo "123456123"| grep -E "(123)456\1"
123456123
(组合)
从正则表达式的左到右:去数左括号的个数
怎么去判定分组的顺序:
就是根据左括号的顺序:从1开始累加
并可以在之后用 \number 转义序列进行再次匹配,
两种用法:提取分组的内容,提取匹配到字符串中你想要部分内容
可以使用\number这种方式去引用,去重复匹配
(?:...):匹配在括号内的任何正则表达式,
但该分组所匹配的子字符串不能在执行匹配后被获取
不能在模式中被引用。不可以使用\number这种方式去引用
(?P<name>…): 命名组合:分组命名
(?P=name): 对前边已定义的分组的引用
(?=...): lookahead assertion: 正向预搜索, 不消耗内容
(?=正则):他是只作为匹配的条件,不会作为结果输出
只作为(?=)前边表达式的限定条件
(?!...):匹配 … 不符合的情况。 negative lookahead assertion
他是只作为匹配的条件,不会作为结果输出
只作为(?=)前边表达式的限定条件,判断后边不是(?!)中的内容
(?<=…): positive lookbehind assertion:正向后视断定(反向预搜索)
他是只作为匹配的条件,不会作为结果输出
只作为(?<=)后边表达式的限定条件
(?<!…):negative lookbehind assertion (后视断定取非)
他是只作为匹配的条件,不会作为结果输出
只作为(?!=)后边表达式的限定条件,判断前边不是(?<!)中的内容
(?(id/name)yes-pattern|no-pattern):
如果给定的 id(组号) 或 name(组名) 存在,将会尝试匹配 yes-pattern
否则就尝试匹配 no-pattern
一、贪婪:尽可能多的匹配
*
+
?(重复0次或1次)
{n}
{n,m}
{n,}
{,m}
二、非贪婪
*?:
+?:
??:
{n,m}?:
1)^word 表示搜索以word开头的内容。
2)word$ 表示搜索以word结尾的内容。
3)^$代表空行不是空格
4). 代表且只能代表一个任意字符。
5)\ 转义字符,让有着特殊身份意义的字符失效。
[root@localhost ~]# echo "aaaaaa" | grep -P "a*"
aaaaaa
[root@localhost ~]# echo "aaaaaa"| grep "a*?"
[root@localhost ~]# echo "aaaaaa" | grep -P "a*?"
aaaaaa
[root@localhost ~]# echo "aaaaaa" | grep -oP "a*?" # -o 代表只输出匹配成功的的
[root@localhost ~]# echo "abcd"|grep -oP "a(b(c))d"
abcd
[root@localhost ~]# echo "abcdbc"|grep -oP "a(b(c))d"
abcd
[root@localhost ~]# echo "abcdbc"|grep -oP "a(b(c))d\1"
abcdbc
[root@localhost ~]# echo "abcdbc"|grep -oP "a(b(c))d\1"
abcdbc
[root@localhost ~]# echo "abcdbcc"|grep -oP "a(b(c))d\1\2"
abcdbcc
#\1代表组一,\2代表组2,以外围括号为准依次组一组二)
[root@localhost ~]# echo "abcd"|grep -oP "a(?:b(c))d"
abcd
[root@localhost ~]# echo "abcdbc"|grep -oP "a(?:b(c))d\1"
[root@localhost ~]#
(以上加了?:分组就没了)
[root@localhost ~]# echo "windows10"| grep -oP "windows(10)"
windows10
[root@localhost ~]# echo "windows9"| grep -oP "windows(10)"
[root@localhost ~]#
[root@localhost ~]# echo "windows10"| grep -oP "windows(?=10)"
windows
[root@localhost ~]# echo "windows9"| grep -oP "windows(?=10)"
[root@localhost ~]#
(上述一段命令用于正则匹配windows10,两个区别就是一个输出后面加的10,一个不输出)
课堂:
[root@rocky ~]# echo "abcd"| grep -oP "a(?P<g1>b(c))(d)"
abcd
[root@rocky ~]# echo "abcdbc"| grep -oP "a(?P<g1>b(c))(d)(?P=g1)"
abcdbc
[root@rocky ~]# echo "windows98"|grep -oP "windows(?=10)"
[root@rocky ~]# echo "windows10"|grep -oP "windows(?=10)"
windows
[root@rocky ~]# echo "windows10"|grep -oP "windows(?!10)"
echo "windows10"|grep -oP "windows(?eval echo $a)"
grep: unrecognized character after (? or (?-
[root@rocky ~]# echo "windows10"|grep -oP "windows(?!=10)"
windows
[root@rocky ~]# echo "windows98"|grep -oP "windows(?!=10)"
windows
[root@rocky ~]# echo "windows98"|grep -oP 'windows(?!10)'
windows
[root@rocky ~]# echo "windows10"|grep -oP 'windows(?!10)'
[root@rocky ~]# echo "10windows"|grep -oP '(?<=10)windows'
windows
[root@rocky ~]# echo "98windows"|grep -oP '(?<=10)windows'
[root@rocky ~]# echo "0windows"|grep -oP '(?<=10)windows'
[root@rocky ~]# echo "0windows"|grep -oP '(?<!10)windows'
windows
[root@rocky ~]# echo "10windows"|grep -oP '(?<!10)windows'
解析下列正则表达式:
(0(?:[.](?:[1-9]\d?|0[1-9]))|[1-9]\d*(?:[.]\d{1,2}|$))
(?:[1-9]\d?|0[1-9]) # ?:代表这个括号的组不能被引用;\d等价于[0-9]
八位强密码的正则表达式(有数字,大小写字母以及字符)
(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[^a-zA-Z0-9]).{8,}
# ?= 是正向预搜索的意思。去搜索有没有这些字符,有就匹配成功,无则匹配失败
sed:
[root@localhost ~]# echo "Hello World" | sed "s/Hello/China/"
China World
(将Hello替换成China)
[root@localhost ~]# vim content_text.sh
Hello World
Hello China
Fuck Japan
[root@localhost ~]# sed "s/Hello/China/" content_text
China World
China China
Fuck Japan
[root@localhost ~]# sed "2 s/Hello/China/" content_text
Hello World
China China
Fuck Japan
(指定第二行)
[root@localhost ~]# sed "/Hello/ s/Hello/Hi/" content_text
Hi World
Hi China
Fuck Japan
(利用正则表达式匹配到Hello则将Hello变成Hi)
[root@localhost ~]# sed "1,3 s/Hello/Hi/" content_text
Hi World
Hi China
Fuck Japan
(替换1~3行)
[root@localhost ~]# sed "0,/Japan/ s/Hello/Hi/" content_text
(表示从起始行到匹配到Japan的行)
[root@localhost ~]# sed "1~2 s/Hello/Hi/" content_text
(表示从第一行开始,每次跳两行。即1、3、5.。。。行)
实验一:04101802001-04101802043正则表达式匹配
[root@localhost ~]# echo "04101802039"|egrep "^041018020(0[0-9]|[1-3][0-9]|4[0-3])$"
04101802039
[root@localhost ~]# echo "04101802029"|egrep "^041018020(0[0-9]|[1-3][0-9]|4[0-3])$"
04101802029
[root@localhost ~]# echo "04101802001"|egrep "^041018020(0[0-9]|[1-3][0-9]|4[0-3])$"
04101802001
[root@localhost ~]# echo "04101802043"|egrep "^041018020(0[0-9]|[1-3][0-9]|4[0-3])$"
04101802043
[root@localhost ~]# echo "04101802044"|egrep "^041018020(0[0-9]|[1-3][0-9]|4[0-3])$"
[root@localhost ~]#
实验二:ipv4地址,邮箱地址,8位强密码,url正则表达式
实验三:sed命令使用:
地址定界和编辑命令的使用,:
#: d命令
i \text命令
c \text命令
#,#: p命令
#~#: s/pattern/string
#,+N: s/pattern/string/g
#,~N: d命令
$:d命令
/regexp/ : a \text
#,/regexp/ : s/pattern/string/g
/regexp/, /regexp/: s/pattern/string/g
[root@localhost ~]# echo "Hello World" | sed "s/Hello/China/"
China World
(将Hello替换成China)
[root@localhost ~]# vim content_text.sh
Hello World
Hello China
Fuck Japan
[root@localhost ~]# sed "s/Hello/China/" content_text
China World
China China
Fuck Japan
[root@localhost ~]# sed "2 s/Hello/China/" content_text
Hello World
China China
Fuck Japan
(指定第二行)
[root@localhost ~]# sed "/Hello/ s/Hello/Hi/" content_text
Hi World
Hi China
Fuck Japan
(利用正则表达式匹配到Hello则将Hello变成Hi)
[root@localhost ~]# sed "1,3 s/Hello/Hi/" content_text
Hi World
Hi China
Fuck Japan
(替换1~3行)
[root@localhost ~]# sed "0,/Japan/ s/Hello/Hi/" content_text
(表示从起始行到匹配到Japan的行)
[root@localhost ~]# sed "1~2 s/Hello/Hi/" content_text
(表示从第一行开始,每次跳两行。即1、3、5.。。。行)
root@localhost ~]# sed '2,~3 s/Hello/Hi/' content_text
Hello World
Hi China
Hi xian
Hello hubei
Hello chongqing
Hello nanjing
Hello hangzhou
Hello xinjiang
(指定从第二行到第三行)
[root@localhost ~]# sed '2,+3 s/Hello/Hi/' content_text
Hello World
Hi China
Hi xian
Hi hubei
Hi chongqing
Hello nanjing
Hello hangzhou
Hello xinjiang
[root@localhost ~]#
(指定第二行开始的三行)
[root@localhost ~]# more content_text
Hello World
Hello China
Hello xian
Hello hubei
Hello chongqing
Hello nanjing
Hello hangzhou
Hello xinjiang
[root@localhost ~]# sed '/hubei/ a \Hello guangzhou' content_text
Hello World
Hello China
Hello xian
Hello hubei
Hello guangzhou
Hello chongqing
Hello nanjing
Hello hangzhou
Hello xinjiang
(在匹配到的行后面加了Hello guangzhou)
[root@localhost ~]# sed '/hubei/ i \Hello shenzhen' content_text
Hello World
Hello China
Hello xian
Hello shenzhen
Hello hubei
Hello chongqing
Hello nanjing
Hello hangzhou
Hello xinjiang
(表示再匹配到的行前面加了Hello shenzhen)
[root@localhost ~]# sed '/hubei/ i \chengdu' content_text
Hello World
Hello China
Hello xian
chengdu
Hello hubei
Hello chongqing
Hello nanjing
Hello hangzhou
Hello xinjiang
(匹配到的行换成了chengdu)
-n,--quiet,--silent:不输出模式空间中的内容,使用安静模式,在一般sed的用法中,所有来自
STDIN的数据一般都会被列出到屏幕上,但如果加上-n参数后,则只有经过sed特殊处理的那一行才会被
列出来;
-i:直接编辑原文件,而不是由屏幕输出,默认不对原文件进行操作;
-e:直接在命令行模式上进行sed的动作编辑,多个子命令之间也可以用分号隔开; sed -e
'command1;command2... filename 或者 sed -e 'command1' -e 'command2' ……filename
-r:使用扩展正则表达式;
-f:直接将sed的动作写在一个文件内,-f filename则可以执行filename内的sed动作。
1)#:#为数字,指定要进行处理操作的行;1,表示第一行;
2)$:表示最后一行,多个文件进行操作的时候,为最后一个文件的最后一行;
3)/regexp/:表示能够被regexp匹配到的行;
regexp即基于正则表达式的匹配;
4)/regexp/I:匹配时忽略大小写;
5)\%regexp%: 任何能够被regexp匹配到的行,换用%(用其他字符也可以,如:#)为边界符号;
6)addr1,addr2:指定范围内的所有的行(范围选定);
常用地址定界表示方式:
a)0,/regexp/:从起始行开始到第一次能够被regexp匹配到的行。
b)/regexp/,/regexp/:被模式匹配到的行内的所有的行。
7)first~step:指定起始的位置及步长,例如:1~2表示1,3,5…
8)addr1,+N:指定行以及以后的N行;
addr1,~N:指定行开始的N行;
注意事项:
1、如果没有指定地址,表示命令将应用于每一行
2、如果只有一个地址,表示命令将应用于这个地址匹配的所有行
3、如果指定了由逗号分隔的两个地址,表示命令应用于匹配第一个地址和第二地址之间的行(包括这
两行)
4、如果地址后面跟有感叹号,表示命令将应用于不匹配该地址的所有行
1)d:删除匹配到的行
2)p:打印当前模式空间内容
3)a \text:append,表示在匹配到的行之后追加内容
4)i \text:insert,表示在匹配到的行之前追加内容
5)c \text:change,表示把匹配到的行和给定的文本进行交换
6)s/regexp/replacement/flages:查找替换,替换regexp匹配到的内容(其中/可以用其他字符代替,
例如@)
其他编辑命令:
常用的flages:
g:全局替换,默认只替换第一个
i: 不区分大小写
p:如果成功替换则打印
7)r 读入文件内容追加到匹配行后面
8)R 读入文件一行内容追加到匹配行后面
9)y :y/source/dest/ 固定长度替换,要求替换的字符串长度相等
10)w /path/to/somefile:将匹配到的文件内容追加到指定的文件末尾
sed 's/north/hello/' datafile --替换每行第一个north
sed 's/north/hello/g' datafile --全部替换
sed '1 s/north/hello/g' datafile --替换第一行所有的north
sed '1 s/north/hello/' datafile --替换第一行第一个north
sed '1 s/north/hello/2' datafile --只替换第一行第二个north