正则表达式(Regular Expression,简称Regex)
我们平时用的*(匹配任意字符)、?(匹配单个字符)是简单的通配符,而正则表达式是它的 “高级版”,能描述更复杂的规则:
查什么,元字符
扩展正则表达式
-E选项启用了 扩展正则表达式(ERE)
-P选项启用了 Perl 兼容正则表达式(PCRE),它支持更强大、更复杂的正则表达式功能,包括一些扩展的功能
#查找包含小写字母的行 grep -P "[a-z]" data.txt#匹配包含ERROR关键字的行 grep -P "ERROR" data.txt例子,提取邮件地址
emile.txt
valid.email@example.com another.email@domain.org invalid-email.com yet.another.email@sub.domain.co.uk 123@numbers.com missingatsign.com email@valid-domain.com not_a_valid_email@com邮箱的通用结构是:用户名@域名
- 用户名:字母、数字、下划线、点、减号
@:必须有且只有一个- 域名:包含
.,不能只有后缀(比如不能是com,必须是example.com)
grep -P '\w+[.\w-]*@[.\w-]+\.\w+' emile.txt\w+:用户名开头,字母数字下划线[.\w-]*:用户名里可以有.、-,任意次数@:必须匹配@[.\w-]+:域名部分(比如example、sub.domain)\.\w+:域名后缀(比如.com、.co.uk)
查多少,匹配符
例子,从日志文件中提取所有包含 IP 地址的行。IP 地址是数字和点号的组合,类似 192.168.0.1
access.log
LNMP => Nginx => PHP(故障) => 500 LNMT => Nginx => Tomcat(故障) => 500 192.168.1.1 - - [07/Jan/2025:12:45:32 +0000] "GET /index.html HTTP/1.1" 200 1024 172.16.0.2 - - [07/Jan/2025:12:46:15 +0000] "POST /login HTTP/1.1" 403 2048 192.168.2.3 - - [07/Jan/2025:12:47:22 +0000] "GET /about.html HTTP/1.1" 200 1024 10.0.0.4 - - [07/Jan/2025:12:48:44 +0000] "GET /contact.html HTTP/1.1" 404 512 invalid_ip - - [07/Jan/2025:12:49:55 +0000] "GET /invalid HTTP/1.1" 400 0grep -P "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" access.log\d{1,3} 匹配 1 到 3 个连续数字,比如1、192、255
\. 匹配一个真实的小数点.,用来分隔 IP 的四段数字
从哪查,定位符
检查 /etc/passwd 文件中是否有用户账户的名称以特定字符(如 "user")开头
grep -P "^user" /etc/passwd去除配置文件中的注释以及空行
grep -vP "^#|^$" nginx.conf-v:取反
^$:空行
|:或者
分组、捕获、反向引用
作用:主要是进行重复数据的匹配操作
举个栗子:1234-1111-1221-3333
要求:要求使用正则匹配1111以及3333这种格式的数字
要求:要求使用正则匹配1221这种格式的数字
☆ 分组
在正则表达式中,通过一对圆括号括起来的内容,我们就称之为"分组"。
\d(\d)(\d)
正则表达式中\d\d\d中,(\d)(\d)就是子表达式,一共有两个()圆括号,则代表两个分组
☆ 捕获
当正则表达式在字符串中匹配到相应的内容后,计算机系统会自动把分组所匹配的到内容放入到系统的对应缓存区中(缓存区从$1开始)
☆反向引用
在正则表达式中,我们可以通过\n(n代表第n个缓存区的编号)来引用缓存区中的内容,我们把这个过程就称之为"反向引用"。
① 查找连续的四个数字,如:3569
grep -P "[0-9]{4}"② 查找连续的相同的四个数字,如:1111
echo "1111" | grep -P "([0-9])\1\1\1"③ 查找数字,如:1221,3443
echo "1221,3443" | grep -P "([0-9])([0-9])\2\1"④ 查找字符,如:AABB,TTMM(提示:A-Z,正则:[A-Z])
cho "AABB,TTMM" | grep -P "([A-Z])\1([A-Z])\2"⑤ 查找连续相同的四个数字或四个字符(提示:\w)
echo "1111" | grep -P "(\w)\1{3}" echo "aaaa" |grep -P "([a-zA-Z0-9_])\1{3}"例子1,从日志中提取特定 IP 地址
场景:在 Web 服务器日志中定位所有来自特定 IP 地址(如 192.168.1.10)的请求,以分析某个用户的访问情况。
192.168.1.10 - - [07/Jan/2025:12:45:32 +0000] "GET /index.html HTTP/1.1" 200 1024 172.16.0.2 - - [07/Jan/2025:12:46:15 +0000] "POST /login HTTP/1.1" 403 2048 192.168.2.3 - - [07/Jan/2025:12:47:22 +0000] "GET /about.html HTTP/1.1" 200 1024 10.0.0.4 - - [07/Jan/2025:12:48:44 +0000] "GET /contact.html HTTP/1.1" 404 512 invalid_ip - - [07/Jan/2025:12:49:55 +0000] "GET /invalid HTTP/1.1" 400 0 grep -P "192\.168\.1\.10" access.loggrep -P "192\.168\.1\.10" test.txt在正则表达式中,.是特殊符号,它默认表示「匹配任意单个字符」。
- 比如正则
192.168会匹配:192x168、192A168、192.168等所有 “192 + 任意字符 + 168” 的字符串,这不是我们想要的。 - 所以要在
.前面加转义符\,把它变成字面意义的小数点.,这样就只会匹配192.168.1.10本身。