Linux 正则表达式

正则表达式

  • 基础正则
  • 拓展正则

正则历史

正则表达式,简写:re,全拼:(regular expression)

在某些地区,管它叫做,正规表达式、规则表达式

正则表达式的"祖先"可以一直上溯至对人类神经系统如何工作的早期研究。Warren McCulloch 和

Walter Pitts 这两位神经生理学家研究出一种数学方式来描述这些神经网络。

1956 年, 一位叫 Stephen Kleene 的数学家在 McCulloch 和 Pitts 早期工作的基础上,发表了一篇标题

为"神经网事件的表示法"的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为"正则集的

代数"的表达式,因此采用"正则表达式"这个术语。

随后,发现可以将这一工作应用于使用 Ken Thompson 的计算搜索算法的一些早期研究,Ken

Thompson 是 Unix 的主要发明人。正则表达式的第一个实用应用程序就是 Unix 中的 qed 编辑器。

如他们所说,剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜

索工具中的一个重要部分。

为什么使用正则

主要目的:

  • 1.方便处理文本和字符串内容

  • 2.处理有规律的内容(手机号,身份证)

  • 3.正则一般给高级开发语言使用

例如:Python,Go,C++,JAVA等(高级开发语言)

awk 和 sed 也是一门语言

搜索和替换操作

但是一般的命令,搜索和替换缺乏灵活性,基本写死。

所以我们可以通过正则表达式,灵活的动态匹配文本。

例如:

  • 1.可以测试输入字符串

    • 以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
  • 2.替换文本。

    • 可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
    • 回车 和 换行
    • \r
    • \n
  • 3.基于模式匹配从字符串中提取子字符串。

  • 4.查找文档内或输入域内特定的文本。

正则和通配符的混淆

# 通配符
* 匹配所有

# 正则
* 代表前面的字符出现0次或多次

在linux中使用正则

  • 修饰符
  • 元字符
# 基础正则
bre (basic regulear expression)

^ 以什么什么开头
$ 以什么什么结尾
. 任意字符
* 前面的字符出现零次或多次
.* 匹配所有字符
[] 主要是一些范围 [0-9] [a-z]
[^] 这是取反 [^0-9]找不是以数字开头的
^[0-9]找以数字开头的
#拓展正则
ere

+ 前面的一个字符或多个字符出现一次或多次
    awk -F '[:,]+' '{print $2}'
    yys sasadasdasdasd 123:abc : 789
    [root@web02 web02]# cat 3.txt | awk -F '[: ]+' '{print $1}'
    yys
    [root@web02 web02]# cat 3.txt | awk -F '[: ]+' '{print $5}'
    789
| 或者

() 被括号起来的东西视为一个整体
    sed 里面做后项引用 (.*)

{} 中间一个非负整数,表示大括号前面的内容出现指定次数
    [1-9].*
    [1-9]+
    [1-9]{1,3} 最少出现一次 最多出现三次

? 前面的内容出现零次或一次  

# 匹配id
[1-90]{1,3}\.

# {}例子
[root@web02 ~]# grep -E 'z{3}'
z 没有匹配到
zz 没有匹配到
zzz 匹配到了
zzz 过滤结果

img

? 前面的内容出现0次或一次

img

img

正则表达式使用误区

通配符有哪些

# 通配符
* 代表所有内容

{} 只要是生成序列
    [root@web02 web02]# echo {1..10}
    1 2 3 4 5 6 7 8 9 10
    [root@web02 web02]# echo {01..10}
    01 02 03 04 05 06 07 08 09 10
    [root@web02 web02]# echo {1..10..2}
    1 3 5 7 9
    [root@web02 web02]# echo {a..z..2}
    a c e g i k m o q s u w y

    cp /usr/lib/systemd/system/nginx.service{.bak} # 展开得下方路径
    cp /usr/lib/systemd/system/{nginx.service,nginx.service.bak}

? 匹配任意一个字符
    [root@web02 web02]# ls -l ./s?udent.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:32 ./student.txt
    [root@web02 web02]# ls -l ./s??dent.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:32 ./student.txt
    [root@web02 web02]# ls -l ./???????.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:32 ./student.txt
    [root@web02 web02]# touch hhh.txt
    [root@web02 web02]# ls -l ./???.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:33 ./hhh.tx

# 以下两个与正则表达式中无异
[] 范围
[^] 以不是这个范围的
    [root@web02 web02]# touch /tmp/check_{1..10}.txt
    [root@web02 web02]# ls -l /tmp/check_[0-9].txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_1.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_2.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_3.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_4.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_5.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_6.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_7.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_8.txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_9.txt
    [root@web02 web02]# ls -l /tmp/check_[0-9][0-9].txt
    -rw-r--r-- 1 root root 0 Jul 6 12:34 /tmp/check_10.txt

正则表达式表格

https://blog.driverzeng.com/4re/
用户名:driverzeng
密码:123@qqdiancom

正则表达式注意事项

  • 1.所有符号皆为英文符号

  • 2.使用三剑客时加引号

  • 3.注意字符集,如果出现字符集问题,那么将字符集修改为C(小概率事件)

  • 4.像素眼(空格,换行符,tab键)

  • 5.测试的时候,推荐使用grep -E或者egrep,因为过滤出来的内容会加颜色

[root@web02 ~]# cat 1.txt 
/tmp    /check_1.txt
/tmp    /check_1.txt

[root@web02 ~]# awk '/\t/{print}' 1.txt teb键
/tmp    /check_1.txt

[root@web02 ~]# awk '/ /{print}' 1.txt  空格
/tmp    /check_1.txt

grep -E与grep的区别

. 任意字符
.* 匹配所有内容

img

img

img

grep -o '.' /etc/passwd

img

正则表达式的修饰符(标记)

  • 用来做标记的

标记也称为修饰符,正则表达式的标记用于指定额外的匹配策略。

标记不写在正则表达式里,标记位于表达式之外,格式如下:

/pattern/flags
/正则表达式/标记
-----------------------------g---------------------------------
%s###g
sed 's###g'
[root@web02 ~]# cat 1.txt 
root
ROOT
[root@web02 ~]# vim 1.txt 
[root@web02 ~]# sed 's#root#ll#g' 1.txt
ll ll
ROOT
[root@web02 ~]# sed 's#root#ll#' 1.txt
ll root
ROOT

-----------------------------m---------------------------------
在Linux中,正则表达式修饰符m(多行模式)用于指定多行文本匹配模式。当使用m修饰符时,某些元字符(如^和$)的行为会发生变化,以实现跨越多行进行匹配。

具体来说,在m修饰符下,以下元字符的含义会发生改变:

^(脱字符):通常情况下,^匹配文本的开头。在m修饰符下,^将匹配每一行的开头。

$(美元符号):通常情况下,$匹配文本的结尾。在m修饰符下,$将匹配每一行的结尾。

.(点号):通常情况下,.匹配除了换行符\n之外的任意字符。在m修饰符下,.将匹配包括换行符在内的任意字符。

这里是一个示例,演示了m修饰符的具体用法:

bash
# 多行匹配示例
text='
Hello
World
'

# 不使用 m 修饰符的正则表达式
echo "$text" | grep '^H.*d$'
# 输出:Hello

# 使用 m 修饰符的正则表达式
echo "$text" | grep -P '(?m)^H.*d$'
# 输出:
# Hello
# World
在上面的示例中,我们使用了两种不同的grep命令来匹配文本。第一个命令grep '^H.*d$'没有使用m修饰符,只匹配了以H开头且以d结尾的文本行,所以只输出了Hello。而第二个命令grep -P '(?m)^H.*d$'使用了m修饰符(通过-P选项启用Perl正则表达式模式),成功地匹配了整个多行文本,并输出了所有匹配的行。
-----------------------------s---------------------------------
sed -i 's#查找内容#替换内容#g' 文件名

正则表达式-元字符

# \t 匹配一个横向制表符 teb键
[root@web02 ~]# echo -e 'adc\t123'
adc 123

# \v 匹配一个垂直制表符
[root@web02 ~]# echo -e 'adc\v123'
adc
   123

[root@web02 ~]# echo -e 'adc\v123\v456'
adc
   123
      456

# \f 换页符
[root@web02 ~]# echo -e 'adc\f123'
adc
   123

[root@web02 ~]# echo -e 'adc\f123\f456'
adc
   123
      456

# \b 匹配一个单词边界,也就是指单词和空格间的位置,例如: 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的'er'
[root@web02 ~]# grep -E '\bnginx\b' /etc/passwd
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
[root@web02 ~]# grep -E 'nginx' /etc/passwd
nginx:x:998:996:Nginx web server:/var/lib/nginx:/sbin/nologin
nginx1:x:1000:1000::/home/nginx1:/bin/bash
nginx2:x:1001:1001::/home/nginx2:/bin/bash

# \B 匹配非单词边界,例如:'er\B' 能匹配 "verb" 中的'er',但不能匹配"never" 中的'er'
# nginx的两包都带带东西才能被匹配出来
[root@web02 ~]# grep -E '\Bnginx\B' /etc/passwd
1nginx23:x:1003:1003::/home/1nginx23:/bin/bash

[root@web02 ~]# grep -E 'nginx\B' /etc/passwd
nginx1:x:1000:1000::/home/nginx1:/bin/bash
nginx2:x:1001:1001::/home/nginx2:/bin/bash
1nginx23:x:1003:1003::/home/1nginx23:/bin/bash

# \d 匹配一个数字字符
匹配从 0 到 9 中的任意一个数字字符(等价于 [0-9])
[root@web02 ~]# cat 2.txt 
1
2
3
4
5
[root@web02 ~]# grep -P '\d' 2.txt 
1
2
3
4
5
[root@web02 ~]# grep -E '\d' 2.txt 

# \n 换行符 
[root@web02 ~]# echo -e 'a\nb'
a
b

# \r 回车
[root@web02 ~]# echo -e 'a\rb'
b

# \w 匹配包括下划线的任意字符 (^[A-Z a-z 0-9])
[root@web02 ~]# cat 2.txt 
1
2
3
4
5
A
s
a
Z
[root@web02 ~]# grep -P '\w' 2.txt 
1
2
3
4
5
A
s
a
Z

# \W 匹配非单词字符串 (^[A-Z a-z 0-9])
[root@web02 ~]# cat 2.txt 
1
2
3
4
5
A
s
a
Z
#
$
%
!
[root@web02 ~]# grep -P '\W' 2.txt 
#
$
%
!

# \s 匹配任何空白字符,包括空格、制表符、换页符等等(等价于[ \f\n\r\t\v])
[root@web02 ~]# grep -P '\s' 2.txt

# \S 匹配任何非空白字符(等价于[^\f\n\r\t\v])
[root@web02 ~]# grep -P '\S' 2.txt 
1
2
3
4
5
A
s
a
Z
#
$
%
!

正则案例

#1.匹配身份证号
##答
[1-9][0-9]{16}([0-9]|x)
#2.匹配手机号
##答
^1[3-9][0-9]{9}
#3.后项引用
(.*) 1
##答
ifconfig eth0 | sed -nr 's#^.*inet (.*)  net.*#\1#gp'
#4.给用户传参中间加上空格(后项引用)
echo 123456
sed -r 's#(.*)#<\1>#g'
sed -r 's#(.)#<\1>#g'
##答
echo "123456" | sed 's#\(.\)#\1 #g'

echo {1..10} 带空格的每个都加上<>
##答
echo {1..10} | sed -E 's#([^ ]+)#<\1>#g'

#5.过滤IP
##答
ifconfig eth0 | sed -nr 's#^.*inet (.*)  net.*#\1#gp'
10.0.0.8
#6.过滤文件中,oldboy和oldbey的内容
[root@web02 ~]# cat 1.txt
oldboy 123
oldbey 456
oldbyy
oldbee
newboy
##答
[root@web02 ~]# grep -E '(\boldboy\b)|(\boldbey\b)' 1.txt 
oldboy 123
oldbey 456

#7.统计上面文件的单词数量
##答
[root@web02 ~]# grep -E '(.*\b)' 1.txt |wc -l
5

#8.统计上面文件的字母数量
##答
[root@web02 ~]# grep -o '[a-z]' 1.txt | wc -l
30

#9.取出下面的指定内容
19:09:03 up 735 days, 23:12, 2 users, load average: 0.00, 0.03, 0.05
19:09:42 up 10:20, 3 users, load average: 0.00, 0.02, 0.05
19:11:24 up 0 min, 1 user, load average: 0.31, 0.08, 0.03
# 如何截取上面的登录用户数?
##答
[root@web02 ~]# sed -r 's#.* (.*) user.*#\1#g' 1.txt 
2
3
1

# 如何截取上面的开机时间?
##答
[root@web02 ~]# sed -E 's#^([0-9]{2}:[0-9]{2}:[0-9]{2}).*#\1#g' 1.txt 
19:09:03
19:09:42
19:11:24
##答
[root@web02 ~]# sed -r 's#.*up ([^,]+),.*#\1#g' 1.txt 
735 days
10:20
0 min

## 因为在Linux中,我们目前只能使用awk grep sed取,而且支持的正则也是基础正则和扩展正则
## 但是有些元字符,基础和扩展正则也不支持,我们只能使用其他语言的正则,比如python
## 于是,在grep命令中,提供了一个选项叫做 -P 这个选项的作用就是,使用perl语言的正则
uptime| grep -Po '[0-9]+(?= user)'
uptime|grep -Po '\d+(?= user)'
uptime|grep -Po '(?<=up).*(?=[0-9] user)'
uptime|grep -Po '(?<=up).*(?=\d user)'
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇