保姆猴教学正则表达式
文章目录
- 保姆猴教学正则表达式
- ERE和BRE
- 1.基本正则表达式和扩展正则表达式的区别
- 1.1扩展表达式ERE独有的
- 正文
- 2.字符匹配 初级
- 3.限定符
- 3.0 尽量多原则
- 3.1 * 任意次
- 3.2 + 至少一次
- 3.3 ? 0次或1次
- 3.4 {n} n次
- 3.5 {n,} 至少n次
- 3.6 {n,m} 至少n次,最多m次
- 3.6.1 缺省后的默认值
- 4. 锚定符
- 4.0 grep,awk,sed用的锚定规则
- 4.1 ^
- 4.2 $
- 4.3 \b
- 4.4 \B
- 4.5 \\<
- 4.6 \\>
- 5.字符匹配 进阶
- 5.1 POSIX字符
- 5.2 perl匹配
- 6. 分组
- 7. | 或
🙊想系统学习并有深刻理解的最好还是跟着视频学。文章只是有个快速勾起记忆作用,只看文章很高效但难免会有难懂的地方。
样例文件
monkey@osp01:/home/osp> cat regex
apple
ppp
play
apple apple
banana!
ERE和BRE
1.基本正则表达式和扩展正则表达式的区别
集合1包含:
| 归类 | 内容 |
|---|---|
| 常用字符匹配 | ^ $ . [ ] [^] |
| 限定符 | * |
| 锚定符 | ^ $ \b \B \< \> |
| POSIX符 | [:lower:] [:upper:]等 |
集合2包含:
| 归类 | 内容 |
|---|---|
| 常限定符 | { } ? + |
| 分组相关 | ( ) | |
-
基本正则可以使用集合1
集合2在基本正则模式下,都视为普通字符串 -
扩展正则可以使用集合1,集合2
集合2在扩展正则模式下,要当作普通字符串需要转义
# 例子 把) 替换为.
# 基本正则,)没有特殊含义,被视为普通字符,无需转义
monkey@osp01:/home/osp> echo "(12 monkeys)" | sed 's/)/./g'
(12 monkeys.
# 扩展正则,()用作分组,有特殊含义,不转义不会被当作普通字符进行匹配
monkey@osp01:/home/osp> echo "(12 monkeys)" | sed -r 's/)/./g'
sed: -e expression #1, char 7: Unmatched ) or \)
# 扩展正则,转义后可正常匹配
monkey@osp01:/home/osp> echo "(12 monkeys)" | sed -r 's/\)/./g'
(12 monkeys.
1.1扩展表达式ERE独有的
这里是专门把扩展正则独有的一些表达式从正文里摘出来,具体例子都写在正文里
| 表达式 | 适用 | 匹配项 | ee | em1 |
|---|---|---|---|---|
| + | ERE | 联合前边的1个字符,此字符连续出现一次或多次,(至少一次) | l+ | apple full |
| ? | ERE | 联合前边的1个字符,此字符出现0次或1次,(连续出现的被当作多个一次,看后边的apple示例,和p*的结果一样,思考一下两者的区别,然后看3.3例子,里边有详细说明区别) | p? | apple play |
| {n} | ERE | 联合前边的1个字符,此字符出现n次 | p{2} | apple play |
| {n,} | ERE | 联合前边的1个字符,此字符出现至少n次 | p{1,} | x*ww |
| {n,m} | ERE | 联合前边的1个字符,此字符出现至少n次,最多m次(<=m) | [sz] | 3oLs.Pz$ |
| () | ERE | 分组 | ||
| | | ERE | 或 |
例子参考 正文 3.限定符
正文
2.字符匹配 初级
基本BRE 和 扩展ERE都可用
| 表达式 | 适用 | 匹配项 | ee | em1 |
|---|---|---|---|---|
| . | BRE ERE | 任意单个字符 | .l | apple full |
| * | BRE ERE | 联合前边的1个字符,此字符连续出现任意次(别误解为通配符哦),包括0次 | p* | apple ppppplay |
| .* | BRE ERE | 连续的任意个数的任意字符(和我们理解中的通配符类似) | p.*e | apple |
| \ | BRE ERE | 转义符,特殊字符 * . \ [ ]等转为普通字符串使用 一个\只转义一个紧跟其后的字符 | \*. | x*ww |
| [ ] | BRE ERE | 匹配指定范围内任意单个字符 | [sz] | 3oLs.Pz$ |
| [^ ] | BRE ERE | 取反 | [^sz] | 3oLs.Pz$ |
1. .
# 正则.l 替换为两个下划线 __
monkey@osp01:/home/osp> echo apple full play | sed 's/.l/__/g'
ap__e f__l __ay
# 有没有想过,这个full,为什么替换完是f__l,不是f___?
# 替换s可以理解为一个"元操作",整体匹配完后,再统一替换,而不是替换成f__l后再把_l匹配上变成f___。
# ul被匹配后,不会再被重复识别,ll也就不会被匹配,所以不会变成我们以为的f___。
2. *
# 正则p* 替换为一个下划线 _
monkey@osp01:/home/osp> echo apple ppp play | sed 's/p*/_/g'
_a_l_e_ _ _l_a_y_
# 解析:
# 除了预想中被替换为_的多个p外,还多了几个_,这些不是其他字母,也不是空格替换而来的,而是“空”替换来的,就是因为p出现0次也会算匹配
# 所以把开头的空替换为_ 各个非连续p的其他字符之间都替换为_ l和e,e和空格,l和a,a和y,y和空
# 对比一下咱们开始预想的结果 a_le _ _lay 发现缺的和上边描述的对上了
🐒: 看了上边俩,是不是也没想象中那么简单,如果不了解,在写脚本时发现对不上,那会找不到原因就糟心了。
主要还是各个博主都想当然认为简单,把这些都只撂一个描述,我从坑里爬出来就给你们来点详细的。
3. .*
monkey@osp01:/home/osp> echo apple all like | sed 's/a.*l/_/g'
_ike
monkey@osp01:/home/osp> echo apple all like full | sed 's/a.*l/_/g'
_
# apple all like 匹配为 apple all l 进行的替换
# apple all like full 匹配为 apple all like full 进行的替换
# !!!注意,我们平常用的通配符,是“就近”,也就是a若干字符,遇到第一个l就结束 -- appl
# 而这个是“趋远”,拿到最后一个为止。
4. \
# 这个简单,就让* . 等有特殊意义的转为普通字符处理
monkey@osp01:/home/osp> echo 3.2!=33 | sed 's/3./_/g'
_2!=_
monkey@osp01:/home/osp> echo 3.2!=33 | sed 's/3\./_/g'
_2!=33
## 没有\转义时,3. 为3和任意字符,所以3. 33都被替换为_
## 转义后,3.为字符串,只有3.被匹配
5. []
# []中各个字符拆分开逐个匹配,所以原式的p 和 l 都会被替换
monkey@osp01:/home/osp> echo apple play full | sed 's/[pl]/_/g'
a___e __ay fu__
6. [^]
# [^]中各个字符拆分开,取反,逐个匹配,所以原式的除了p 和 l 其他字符都会被替换
monkey@osp01:/home/osp> echo apple play full | sed 's/[^pl]/_/g'
_ppl__pl_____ll
3.限定符
(个数匹配,都遵循 3.0尽量多原则)
| 表达式 | 适用 | 匹配项 | ee | em1 |
|---|---|---|---|---|
| * | BRE ERE | 联合前边的1个字符,此字符连续出现任意次,包括0次 | p* | apple ppppplay |
| + | ERE | 联合前边的1个字符,此字符连续出现一次或多次,(至少一次) | p+ | apple |
| ? | ERE | 联合前边的1个字符,此字符出现0次或1次,(连续出现的被当作多个一次)(和+,*的结果一样?看例子3.3里有详细说明区别) | p? | apple play |
| {n} | ERE | 联合前边的1个字符,此字符出现n次 | p{3} | pp pppplay |
| {n,} | ERE | 联合前边的1个字符,此字符出现至少n次 是{n,m}的一个缺省,常用所以单独列出来。 | p{2,} | pp play |
| {n,m} | ERE | 联合前边的1个字符,此字符出现至少n次,最多m次(<=m) | p{2,3} | pp ppp pppp |
3.0 尽量多原则
🙉捡西瓜,丢芝麻
# 这个,至少3个p时,转化成.,结果会有几个点呢?
pp ppp pppp ppppp
# 尽量少原则的预想结果 pp . .p .pp
# 尽量多原则的预想结果 pp . . .
# 实际结果:
monkey@osp01:/home/osp> echo pp ppp pppp ppppp | sed -r 's/p{3,}/./g'
pp . . .
# 说明他们遵循尽量多原则,满足3个时,继续往后,直到不是目标字符p为止,"尽可能多地拿"。
# !!每个限定符号,都遵循尽量多原则
# ? 匹配0个和1个的尽量多
# 匹配0个后,要尽量多,所以继续往后匹配,当下一个字符为目标p,则就按照p来匹配,显示的是. 而不是..
# 有几个p就有几个.,和p{1}的结果一致,有1个就不要0个
monkey@osp01:/home/osp> echo pp ppp pppp ppppp | sed -r 's/p?/./g'
.. ... .... .....
# 再来个不是p的,只能匹配0个字符的对照以下
monkey@osp01:/home/osp> echo oo ooo oooo ooooo | sed -r 's/p?/./g'
.o.o. .o.o.o. .o.o.o.o. .o.o.o.o.o.
# 很好记,如果是尽量少,那就无限个点了,因为可以一直拿0。
3.1 * 任意次
# 任意个数连续p,包括0个
monkey@osp01:/home/osp> echo apple ppp play | sed 's/p*/_/g'
_a_l_e_ _ _l_a_y_
3.2 + 至少一次
# 至少1个连续p
# 注意加-r,扩展正则
monkey@osp01:/home/osp> echo apple ppp play | sed -r 's/p+/_/g'
a_le _ _lay
3.3 ? 0次或1次
# 0或1个p
# 注意加-r,扩展正则
monkey@osp01:/home/osp> echo apple ppp play | sed -r 's/p?/_/g'
_a__l_e_ ___ _l_a_y_
# 来讲解 一下 ppp 被*处理时 和 被? 处理时的区别
# * 0个或任意个,多个p会被当作一个整体,匹配一次
monkey@osp01:/home/osp> echo apple ppp play | sed -r 's/p*/_/g'
_a_l_e_ _ _l_a_y_
# ? 0个或1个,多个p被匹配多次
monkey@osp01:/home/osp> echo apple ppp play | sed -r 's/p?/_/g'
_a__l_e_ ___ _l_a_y_
# 其实也是尽量多原则的结果,任意次就是尽量多拿无限个处理一次,而?,尽量多,最多接受1,还是一个个处理。
3.4 {n} n次
# 注意加-r,扩展正则
monkey@osp01:/home/osp> echo apple ppp play | sed -r 's/p{2}/_/g'
a_le _p play
3.5 {n,} 至少n次
monkey@osp01:/home/osp> echo pp ppp pppp ppppp | sed -r 's/p{3,}/./g'
pp . . .
3.6 {n,m} 至少n次,最多m次
monkey@osp01:/home/osp> echo pp ppp pppp ppppp | sed -r 's/p{3,4}/./g'
pp . . .p
看完这个有的🙈就开始了,那n>m时咋样呢?{3,2} {9,3} …
monkey@osp01:/home/osp> echo pp pppplay | egrep "p{3,2}"
grep: Invalid content of \{\}
# 为什么报这个错呢?
# 推测{n,m}这个扩展正则,会先累计一个长度为n的空间往里塞尽量足够的值,再根据n往后加入m-n个值...
# 这个错会在匹配实际值前就爆出来...
# 我也不知道,这小猴喜欢n>m,喜欢{3,2}??? 自己研究去。
那个🙈去罚站,剩余🙊继续看。
- {0,1}等同于?
- {,1}等同于? 看3.6.1缺省后的默认值
- {0,}等同于* 看3.6.1缺省后的默认值
- {1,}等同于+
- n,m两个值相等时等同于{n}
🙈: {,}是什么…
🐒: 叫家长!
# {,} 可以理解作为{0,∞} 结果和*相同,参考3.6.1 缺省后的默认值
monkey@osp01:/home/osp> echo pp ppp pppp ppppp | sed -r 's/p{,}/./g'
. . . .
monkey@osp01:/home/osp> echo aa | sed -r 's/p{,}/./g'
.a.a.
3.6.1 缺省后的默认值
# n缺省默认为0
# {,1} 匹配0个,1个,结果和{0,1} 和 ? 一样
monkey@osp01:/home/osp> echo apple ppp play | sed -r 's/p{,1}/./g'
.a..l.e. ... .l.a.y.
# m缺省默认无穷大,{,m}匹配至少0个,至多m个
monkey@osp01:/home/osp> echo pp ppp pppp ppppp | sed -r 's/p{3,}/./g'
pp . . .
4. 锚定符
也叫定位符
指代被处理内容的某个位置,而不是某个位置的字符,比如abc, ^ 指代的不是开头字母a,而是开头的位置,a之前。
BRE:基本正则 ERE:扩展正则
| 表达式 | 适用 | 匹配项 |
|---|---|---|
| ^ | BRE ERE | 指代文件每行行首 |
| $ | BRE ERE | 指代文件每行行尾 |
| \b | BRE ERE | 指代单词边界 |
| \B | BRE ERE | 非单词边界 |
| \< | BRE ERE | 单词开头 |
| \> | BRE ERE | 单词结尾 |
4.0 grep,awk,sed用的锚定规则
BRE:基本正则 ERE:扩展正则
| 表达式 | 适用 | 匹配项 | 备注 | 例子 |
|---|---|---|---|---|
| ^ | BRE ERE | 指代文件每行行首 | 注意区别于中括号中的取反[^] 一般字符都在后边,写前边没有意义 匹配^后的字符串出现在行首 | grep “^ap” 匹配以ap开头的行 |
| $ | BRE ERE | 指代文件每行行尾 | 一般字符都在前边,写前边,写前边,写之后无意义 匹配^后的字符串出现在行尾部 | grep "le$" 匹配以le结尾的行 |
| \b | BRE ERE | 指代单词边界 | 单词指的是一个连续的非特殊字符组成的词块 导致词块分界的可以是连续多个特殊符号 边界是抽象的,只分割词块,不实际存在 看完4.3例子就懂了 | / |
| \B | BRE ERE | 非单词边界 | 单词是连续特殊字符时,也生效 边界是抽象的,只分割词块,不实际存在 它不严格代表单词内部,其实是\b的相反结果 看例子4.4 | / |
| \< | BRE ERE | 单词开头 | / | / |
| \> | BRE ERE | 单词结尾 | / | / |
monkey@osp01:/home/osp> cat regex
apple
ppp
play
apple apple
banana!
4.1 ^
🐒:注意看例子里的sed用法,匹配按行但是处理不是整行处理
# ^pl grep 匹配以pl为首的行
monkey@osp01:/home/osp> grep "^pl" regex
play
# ^pl sed 把行开头的pl替换为.,其他位置不改
sed "s/^pl/./g" regex
apple
ppp
.ay
apple apple
banana!
4.2 $
🐒:注意看例子里的sed用法,匹配按行但是处理不是整行处理
# le$ grep 匹配以le结尾的行
monkey@osp01:/home/osp> grep "le$" regex
apple
apple apple
# le$ sed 把行尾部的le替换为.,其他位置不改
monkey@osp01:/home/osp> sed 's/le$/./g' regex
app.
ppp
play
apple app.
banana!
4.3 \b
\b基本使用
# \b
# 边界处替换为|
monkey@osp01:/home/osp> echo app apple and | sed 's/\b/|/g'
|app| |apple| |and|
# 以app为边界的单词,把匹配内容app换为.
monkey@osp01:/home/osp> echo app apple and | sed 's/\bapp/./g'
. .le and
问题探讨:
app,apple 是当作app和apple 两个单词,还是算app,apple一个字串,实际是app和apple两个单词
也就是说任意特殊符号都作为单词分界的标志,而不只是我们印象里的空格。
# 开头为a的单词中的匹配内容a替换为.
monkey@osp01:/home/osp> echo app,apple,and | sed 's/\ba/./g'
.pp,.pple,.nd
# 中文逗号
monkey@osp01:/home/osp> echo 123,123,123 | sed 's/\b12/./g'
.3,.3,.3
# 每个单词开头的a都被匹配了 说明特殊符号可以分隔单词
🐒:出来,🙈
🙈:数字呢?中文呢?符号组成的算不算呢?
# 数字 12 改为.
echo 123,123,123 | sed 's/\b12/./g'
.3,.3,.3
# 中文 张 改为.
echo 张麻子,张牧之 | sed 's/\b张/./g'
.麻子,.牧之
# 中文 而且是中文逗号, 也可以作为分界的标志
echo 张麻子,张牧之 | sed 's/\b张/./g'
.麻子,.牧之
# 看符号
monkey@osp01:/home/osp> echo @@ @@ | sed 's/\b/|/g'
@@ @@
monkey@osp01:/home/osp> echo @@,@@ | sed 's/\b/|/g'
@@,@@
monkey@osp01:/home/osp> echo ,, ,, | sed 's/\b/|/g'
,, ,,
# 上边的例子没有任何替换为|,说明单词指的这个词块,对特殊字符不生效(词块不可包含特殊字符)。
# 分界处替换为|,可以看到词块不包含特殊字符,
monkey@osp01:/home/osp> echo ,12,12 | sed 's/\b/|/g'
,|12|,|12|
# 两个符号.和, ,依旧没有被当作被.分隔的单词
# 多个特殊符号,之后的符号也不会被界定为单词的一部分,也就是连续多个特殊符号整体当作分界标志
monkey@osp01:/home/osp> echo ,12.,12 | sed 's/\b/|/g'
,|12|.,|12|
这就是上边表格备注的 --连续的非特殊字符组成的词块
导致词块分界的可以是连续多个特殊符号
还有一句,什么叫边界是抽象的,只分割词块,不实际存在
# 12,12,345 分隔符为, 此时我想匹配 单词边界 且边界后为,12,34的值替换为_
# 假如边界具有实际效用,强行分界,那么 边界12边界,边界12边界,边界345边界
# 这样 \b,12,34 要匹配的 边界,12,34 是匹配不到的,因为后边都被分界,不是同一个单词了
# 但实际情况:
monkey@osp01:/home/osp> echo 12,12,345 | sed 's/\b,12,34/|/g'
12|5
# 所以是一个弱分界,或者说抽象分界,并不实际存在。
4.4 \B
基本用法
# 把非单词边界替换为|
monkey@osp01:/home/osp> echo app apple and | sed 's/\B/|/g'
a|p|p a|p|p|l|e a|n|d
# 同样的,分界是抽象的,不实际存在
monkey@osp01:/home/osp> echo app apple and | sed 's/\Bpp/_/g'
a_ a_le and
# 对特殊符号组成的词块生效
monkey@osp01:/home/osp> echo ,,,@,,, | sed 's/\B/|/g'
|,|,|,|@|,|,|,|
monkey@osp01:/home/osp> echo ,,,x,,, | sed 's/\B/|/g'
|,|,|,x,|,|,|
# 这个和我们理解单词内部不同,它只是\b单词边界的相反集合
# 所以,\B不严格代表单词内部,其实是\b的相反结果
4.5 \<
# \<
# 单词首处替换为|
monkey@osp01:/home/osp> echo app apple and | sed 's/\b/|/g'
|app |apple |and
# 单词首为app的单词,把匹配内容app换为.
monkey@osp01:/home/osp> echo app apple and | sed 's/\<app/./g'
. .le and
4.6 \>
# 单词尾处替换为|
monkey@osp01:/home/osp> echo app apple and | sed 's/\>/|/g'
app| apple| and|
# 单词尾后拼接为,ap的单词,把匹配内容,ap换为.
monkey@osp01:/home/osp> echo app,apple,and | sed 's/\> ap/./g'
app.ple,and
5.字符匹配 进阶
5.1 POSIX字符
指定的是一个格式或者说标准,使用时配合[ ]匹配范围内任意字符或[ ^ ]取反, 比如 [[:alnum:]] [^[:alnum:]]
[[:alnum:]] POSIX字符失效,匹配不到正确的值可以尝试[]与POSIX字符之间加上空格 [ [:alnum:] ]
如果只写[:alnum:],就会被识别为[] 和 :alnum:,也就是匹配 :alnum这几个字符
| 表达式 | 适用 | 范围 | em1 | em2 |
|---|---|---|---|---|
| [:alnum:] | BRE ERE | 字母和数字 [[:alnum:]]等同于[0-9a-zA-Z] | 11 cans ! | |
| [:alpha:] | BRE ERE | 字母 [[:alpha:]]等同于[a-zA-Z] 等同\a ,但\a在grep,awk,sed中不支持 | 11 cans ! | 11 Cans ! |
| [:digit:] | BRE ERE | 数字 [[:digit:]]等同于[0-9] 等同\d,但\d在grep,awk,sed中不支持 | 11 cans ! | |
| [:graph:] | BRE ERE | 非空字符(可见的字符) | 看例子4 | |
| [:lower:] | BRE ERE | 小写字母 [[:lower:]]等同[a-z] 等同\l,但\l在grep,awk,sed中不支持 | Monkey | |
| [:upper:] | BRE ERE | 大写字母 [[:upper:]]等同[A-Z] 等同\u,但\u在grep,awk,sed中不支持 | Monkey | |
| [:print:] | BRE ERE | 可打印字符(包括空格) 等同\p,但\p在grep,awk,sed中不支持 | 看例子7 | |
| [:punct:] | BRE ERE | 标点符号 | You’re a monkey. | |
| [:space:] | BRE ERE | 空白字符(换行\n\r,空格 ,制表符\t,换页符\f) 等同\s,grep,awk,sed支持 | 看例子9 | |
| [:cntrl:] | BRE ERE | 控制字符 ASCII 0到31位和127位 \a响铃 \b退格 \r回车 \f换页符等,可以理解为匹配所有不可见符 | 看例子10 | |
| [:xdigit:] | BRE ERE | 十六进制数字 本身不区分十进制还是十六进制,也不区分字符串,只是可以接受ABCDEF作为数字一部分 等同\x,但\x在grep,awk,sed中不支持 | A1B = 2587 | GAX F1 |
| [:blank:] | BRE ERE | 空格和水平制表符\t | 看例子12 |
- 例子
#1 [:alnum:]字母和数字替换为.
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed 's/[[:alnum:]]/./g'
(.. .......)
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed 's/[0-9a-zA-Z]/./g'
(.. .......)
# 非字母和数字替换为.
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed 's/[^[:alnum:]]/./g'
.11.monkeys.
#2 [:alpha:]字母替换为.
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed 's/[[:alpha:]]/./g'
....monkeys.
# 非字母替换为.
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed 's/[^[:alpha:]]/./g'
....monkeys.
#3 [:digit:]数字替换为.
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed 's/[[:digit:]]/./g'
....monkeys.
# 非数字替换为.
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed 's/[^[:digit:]]/./g'
.11.........
#4 [:graph:] 非空字符(可见字符)
# 看替换前
monkey@osp01:/home/osp> echo -e "apple\twatermelon\norange"
apple watermelon
orange
# 非空字符替换为.
monkey@osp01:/home/osp> echo -e "apple\twatermelon\norange" | sed 's/[[:graph:]]/./g'
..... ..........
......
#5 [:lower:] 小写字母
monkey@osp01:/home/osp> echo "Apple" | sed 's/[[:lower:]]/./g'
A....
#6 [:upper:] 大写字母
monkey@osp01:/home/osp> echo "Apple" | sed 's/[[:upper:]]/./g'
.pple
#7 [:print:] 可打印字符(包括空格)
# 看替换前 \b表示回退(删除键)
monkey@osp01:/home/osp> echo -e "apple\twatermelon\borange banana"
apple watermeloorange banana
# 加了^,把 非 可打印字符替换为.
monkey@osp01:/home/osp> echo -e "apple\twatermelon\borange banana" | sed 's/[^[:print:]]/./g'
apple.watermelon.orange banana
# 可见 \t,\b都属于不可打印字符,空格属于可打印字符
#8 [:punct:] 标点符号
# 标点符号替换为@
monkey@osp01:/home/osp> echo "I'm a nanny, you're a monkey. (ok)" | sed 's/[[:punct:]]/@/g'
I@m a nanny@ you@re a monkey@ @ok@
#9 [:space:] 空白字符(新行,空格,制表符)
# a1 a2 a3 ... a7
# 空格 \t水平制表符 \n换行符 \f \r换行符 \v垂直制表符
# 看替换前,为了不被空格干扰,就不写多余空格
monkey@osp01:/home/osp> echo -e "a1 a2\ta3\na4\fa5\ra6\va7"
a1 a2 a3
a4
a6a5
a7
# 空白字符(\r \f \t 空格 \n)替换为.
monkey@osp01:/home/osp> echo -e "a1 a2\ta3\na4\fa5\ra6\va7" | sed 's/[[:space:]]/./g'
a1.a2.a3
a4.a5.a6.a7
## 对\n不生效(不是正则错误,是linux换行符的问题,识别\r为换行符)
#10 [:cntrl:] 控制字符
# ASCII 13位\t替换为.
monkey@osp01:/home/osp> echo -e "a\tb\fc\vd\ne\af\bg\rh" | sed 's/[[:cntrl:]]/./g'
a.b.c.d
e.f.g.h
## 对\n不生效(不是正则错误,是linux换行符的问题,识别\r为换行符)
#11 [:xdigit:] 十六进制数字
# 本身不区分十进制还是十六进制,也不区分字符串,只是可以接受ABCDEF作为数字一部分
# 其实就是[0-9A-F]
monkey@osp01:/home/osp> echo ABCDEF 123 GHI | sed 's/[[:xdigit:]]/./g'
...... ... GHI
#12 [:blank:] 空格和TAB
# 看替换前
monkey@osp01:/home/osp> echo -e "apple\twatermelon"
apple watermelon
# 空格和\t替换为.
monkey@osp01:/home/osp> echo -e "apple\twatermelon" | sed 's/[[:blank:]]/./g'
apple.watermelon
以下表达式依旧配合[]或[^]使用,[ ]中可以使用多个,或关系,比如[A-Z0-9]表示大写字母或数字都可以匹配
| 表达式 | 适用 | 范围 | em1 |
|---|---|---|---|
| A-Z | BRE ERE | 大写字母 | CANS cans |
| a-z | BRE ERE | 小写字母 | CANS cans |
| 0-9 | BRE ERE | 数字 | 11 cans |
| [\u4e00-\u9fa5] | BRE ERE | 中文 中文汉字正则表达式为[\u4e00-\u9fa5],但是grep,awk,sed不支持 | 看 11 monkeys |
5.2 perl匹配
| 表达式 | 作用 | 备注 |
|---|---|---|
| \o | 八进制[0-7] | grep,awk,sed中不支持 |
| \O | 非八进制[^0-7] | grep,awk,sed中不支持 |
| \w | 连续数字或字母组成的词块 (单词)[[:alnum:]] | grep,awk,sed中支持 |
| \W | 非单词 [^[:alnum:]] | grep,awk,sed中支持 |
| \a | 字母 | grep,awk,sed中不支持 |
| \A | 非字母 | grep,awk,sed中不支持 |
| \l | 小写字母 | grep,awk,sed中不支持 |
| \L | 非小写字母 | grep,awk,sed中不支持 |
| \u | 大写字母 | grep,awk,sed中不支持 |
| \U | 非大写字母 | grep,awk,sed中不支持 |
| \s | 空格符 | grep,awk,sed中支持 |
| \S | 非空格符 | grep,awk,sed中支持 |
| \d | 数字 | grep,awk,sed中不支持 |
| \D | 非数字 | grep,awk,sed中不支持 |
| \x | 十六进制数字(匹配0-9和ABCDEF) | grep,awk,sed中不支持 |
| \X | 非十六进制数字 | grep,awk,sed中不支持 |
| \p | 可打印字符 | grep,awk,sed中不支持 |
| \P | 非可打印字符 | grep,awk,sed中不支持 |
# \w
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed -r 's/\w/./g'
(.. .......)
# \W
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed -r 's/\W/./g'
.11.monkeys.
#\s 空白字符替换为.
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed -r 's/\s/./g'
(11.monkeys)
#\S 非空白字符替换为.
monkey@osp01:/home/osp> echo "(11 monkeys)" | sed -r 's/\S/./g'
... ........
6. 分组
使用()进行分组,把()中的字符当作一个整体进行处理
# {1}限定符,前一个单位出现1次,需要-r扩展表达式
monkey@osp01:/home/osp> echo "ababab abbb" | sed -r 's/ab{3}/_/g'
ababab _
# 给ab划为一组 (ab)
monkey@osp01:/home/osp> echo "ababab abbb" | sed -r 's/(ab){3}/_/g'
_ abbb
# 嵌套组
# ab单位重复2次,拼接c 即 ababc
# + 限定符,前一个单位出现1次或多次
monkey@osp01:/home/osp> echo "ababc ababcababc" | sed -r 's/((ab){2}c)+/_/g'
_ _
7. | 或
# 把a 或者 多个c 替换为.
monkey@osp01:/home/osp> echo "ca aa cc ac" | sed -r 's/a|c+/./g'
.. .. . ..
# 分组后 把多个 (a或者c) 替换为.
monkey@osp01:/home/osp> echo "ca aa cc ac" | sed -r 's/(a|c)+/./g'
. . . .
969

被折叠的 条评论
为什么被折叠?



