正则表达式

  • REGEXP:Regular Expressions,由一类特殊字符及文本符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能
  • 程序支持:grep,sed,awk,vim,less,nginx,varnish等
  • 分两类:
    • 基本正则表达式:BRE
    • 扩展正则表达式:ERE
      • grep -E,egrep
  • 正则表达式引擎:
    • 采用不同算法,检查处理正则表达式的软件模块
    • PCRE(Perl Compatible Regular Expressions)
  • 元字符分类:字符匹配、匹配次数、位置锚定、分组
  • man 7 regex

image.png
image.png
Windos
C:\Users\28710>findstr /?
在文件中寻找字符串。
FINDSTR [/B] [/E] [/L] [/R] [/S] [/I] [/X] [/V] [/N] [/M] [/O] [/P] [/F:file]
[/C:string] [/G:file] [/D:dir list] [/A:color attributes] [/OFF[LINE]]
strings [[drive:][path]filename[ …]]
/B 在一行的开始配对模式。
/E 在一行的结尾配对模式。
/L 按字使用搜索字符串。
/R 将搜索字符串作为一般表达式使用。
/S 在当前目录和所有子目录中搜索匹配文件。
/I 指定搜索不分大小写。
/X 打印完全匹配的行。
/V 只打印不包含匹配的行。
/N 在匹配的每行前打印行数。
/M 如果文件含有匹配项,只打印其文件名。
/O 在每个匹配行前打印字符偏移量。
/P 忽略有不可打印字符的文件。
/OFF[LINE] 不跳过带有脱机属性集的文件。
/A:attr 指定有十六进位数字的颜色属性。请见 “color /?”
/F:file 从指定文件读文件列表 (/ 代表控制台)。
/C:string 使用指定字符串作为文字搜索字符串。
/G:file 从指定的文件获得搜索字符串。 (/ 代表控制台)。
/D:dir 查找以分号为分隔符的目录列表
strings 要查找的文字。
[drive:][path]filename
指定要查找的文件。
除非参数有 /C 前缀,请使用空格隔开搜索字符串。
例如: ‘FINDSTR “hello there” x.y’ 在文件 x.y 中寻找 “hello” 或
“there”。’FINDSTR /C:”hello there” x.y’ 文件 x.y 寻找
“hello there”。
一般表达式的快速参考:
. 通配符: 任何字符
* 重复: 以前字符或类出现零或零以上次数
^ 行位置: 行的开始
$ 行位置: 行的终点
[class] 字符类: 任何在字符集中的字符
[^class] 补字符类: 任何不在字符集中的字符
[x-y] 范围: 在指定范围内的任何字符
\x Escape: 元字符 x 的文字用法
\ xyz> 字位置: 字的结束
有关 FINDSTR 常见表达法的详细情况,请见联机命令参考。

基本正则表达式元字符

  • 字符匹配
    • . 匹配任意单个字符
    • [] 匹配指定范围内的任意单个字符,示例:[wang] [0-9] [a-z] [a-zA-Z]
    • [^] 匹配指定范围外的任意单个字符
    • [:alnum:] 字母和数字
    • [:alpha:] 代表任何英文大小写字符,亦即A-Z,a-z
    • [:lower:] 小写字母 [:upper:] 大写字母
    • [:blank:] 空白字符(空格和制表符)
    • [:space:] 水平和垂直的空白字符(比[:blank:]包含的范围广)
    • [:cntrl:] 不可打印的控制字符 (退格、删除、警铃…)
    • [:digit:] 十进制数字 [:xdigit:] 十六进制数字
    • [:graph:] 可打印的非空白字符
    • [:print:] 可打印字符
    • [:punct:] 标点符
  • 匹配次数:用在要指定次数的字符后面,用于指定前面的字符要出现的次数
  • 匹配前面的字符任意次,包括0次
    贪婪模式:尽可能长的匹配
    . 任意长度的任意字符
    \? 匹配其前面的字符0或1次
    + 匹配其其前面的字符至少1次
    {n} 匹配前面的字符n次
    {m,n} 匹配前面的字符至少m次,至多n次
    {,n} 匹配前面的字符至多n次
    {n,} 匹配前面的字符至少n次
    取ip地址:
    ifconfig ens3 | grep -o “[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}“ |head -n1
    107.191.53.9
    *ifconfig eth0 | grep -o “([0-9]{1,3}.){3}[0-9]{1,3}“ | head -n1

    10.0.0.5
  • 定位锚定:定位出现的位置
    • ^行首锚定,用于模式的最左侧
    • $行尾锚定,用于模式的最右侧
    • ^PATTERN$ 用于模式匹配整行
      • ^$ 空行
      • ^[[:space:]]*$ 空白行
    • \< 或 \b 词首锚定,用于单词模式的左侧
    • > 或 \b 词组锚定,用于单词模式的右侧
    • \ 匹配整个单词
  • 分组:()将一个或多个字符捆绑在一起,当作一个整体处理,如:(root)+ 匹配root至少出现一次
  • 分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:\1,\2,\3…
  • \1表示从左侧起第一个左括号以及与之匹配右括号之间的模式所匹配到的字符
  • 示例:(string1+(string2)*)

\1: string1+(string2)*
\2:string2

  • 后向引用:引用前面的分组括号中的模式所匹配字符,而非模式本身
  • 或者:|
    • 示例:a|b a或b C|cat:C或cat (C|c)at:Cat或cat
元字符 定义
^ 行首
$ 行尾
. 任意单一字符
[] []内任意单一字符
[^] 除[]内任意单一字符
* *前面字符重复不确定次数
\+ \+前面字符重复一次以上不确定次数
\? ?前面字符重复0或1次
\ 转义符
.* 任意长度字符
\{n\} 前面字符重复n次
\{n,\} 前面字符重复n次以上
\{m,n\} 前面字符重复m次和n次之间
[:alnum:] 字母和数字
[:alpha:] 代表任何英文大小写字符,亦即A-Z,a-z
[:lower:] 小写字母
[:upper:] 大写字母
[:blank:] 水平空白字符(空格和制表符)
[:space:] 所有水平和垂直的空白字符(比[:blank:]包含的范围广)
[:cntrl:] 不可打印的控制字符(退格、删除、警铃…)
[:digit:] 十进制数字
[:graph:] 可打印非空白字符
[:print:] 可打印字符
[:punct:] 标点符号
[:xdigit:] 十六进制数字

练习

1、显示/proc/meminfo文件中以大小s开头的行(要求:使用两种方法)
方式1:
cat /proc/meminfo | grep ‘^[Ss]’
方式2:
sed -r ‘/^[Ss]/p’ /proc/meminfo -n
2、显示/etc/passwd文件中不以/bin/bash结尾的行
方式1:扩展正则表达式
egrep -v ‘(/bin/bash)$’ /etc/passwd
方式2:正则表达式
grep -v ‘(\/bin\/bash)$’ /etc/passwd
3、显示用户rpc默认的shell程序
方式1:
cat /etc/passwd | egrep ‘rpc[^[:alnum:]]’ | cut -d: -f1,7
rpc:/sbin/nologin
方式2:
awk -F: ‘/^rpc[^[:alnum:]]/{print $1,$7}’ /etc/passwd
rpc /sbin/nologin
4、找出/etc/passwd中两位或三位数
cat /etc/passwd | egrep ‘[^0-9][[:digit:]]{2,3}[^0-9]’ -o | awk -F: ‘{print $2}’
5、显示CentOS7的/etc/grub2.cfg文件中,至少以一个空白字符开头的且后面有非空白字符的行
cat /etc/grub2.cfg |egrep ‘^[[:space:]].[^[:space:]].$’
6、找出”netstat -tan”命令结果中以LISTEN后跟任意多个空白字符结尾的行
netstat -tan | egrep ‘LISTEN[[:space:]]{2,}$’
7、显示CentOS7上所有系统用户的用户名和UID
awk -F: ‘{if($3<1000) print $1,$3}’ /etc/passwd
8、添加用户bash、testbash、basher、sh、nologin(其shell为/sbin/nologin),找出/etc/passwd用户名和shell同名的行
cat /etc/passwd | egrep “^(.)(:.)\1$”
9、利用df和grep,取出磁盘各分区利用率,并从大到小排序
df -h | egrep ‘^/dev/‘ | awk ‘{print $5}’ | sed -r ‘s/(.*)%/\1/‘ | sort -nr
正则表达式:
1、QQ号 5~11位
283231
233333333331
322222222
123
4444444444444444444444
grep ‘^[0-9]{5,11}$’ file.txt
sed -n -r ‘/^[0-9]{5,11}$/p’ file.txt
2、身份证号
31242619651221026X
122333333333333333
egrep ‘^[1-9]{6}(18|19|20)[0-9]{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)[0-9]{3}[0-9Xx]$’ file2.txt
sed -n -r ‘/^[1-9]{6}(18|19|20)[0-9]{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)[0-9]{3}[0-9Xx]$/p’ file2.txt
3、手机号
4、邮箱
复习正则表达式:
. 任意的一个字符
[^mage.] .本身 ^排除
^mage
wang$
[[:upper:]]
xyz{10}
(xyz){10}
\? 0,1 可有可无
x+ 至少1次
x{1,}
\< \b 词首
> \b 词尾

egrep及扩展的正则表达式

  • egrep = grep -E
  • egrep [OPTIONS] PATTERN [FILE…]
  • 扩展正则表达式的元字符
  • 字符匹配:

    • . 任意单个字符
    • [] 指定范围的字符
    • [^] 不在指定范围的字符

      扩展正则表达式

  • 次数匹配:

  • 匹配前面字符任意次
    ? 0或1次
    + 1次或多次
    {m} 匹配m次
    {m,n} 至少m,至多n次
  • 位置锚定:

^ 行首
$ 行尾
\<,\b 词首
>,\b 词尾

  • 分组

()
后向引用:\1,\2,…

  • 或者:

a|b a或b
C|cat C或cat
(C|c)at Cat或cat

练习

image.png

3、basename 取基名
dirname 取目录名
取基名
echo “/etc/rc.d/init.d/functions” | grep -Eo “[^/]+$”
functions
取目录名
echo “/etc/rc.d/init.d” | grep -Eo “./.[^/]” | grep -Eo “./“
/etc/rc.d/
echo “/etc/rc.d/init.d” | grep -Eo “.
[^/]” | grep -Eo “./“
/etc/rc.d/
6、
image.png
0-255:
[1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]
7、
*ifconfig | grep -Eo “(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])”

10.0.0.5
255.255.255.0
10.0.0.255
127.0.0.1
255.0.0.0