分享

正则表达式之基础正则表达式

 Coder编程 2022-11-08 发布于北京

基础正则表达式 BRE

最常用的一些简单的正则表达式。

基本概念

  • 正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。

  • 元字符就是指那些在正则表达式中具有特殊意义的专用字符。

  • 构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。

普通字符

普通字符包括没有显式指定为元字符的所有可打印和不可打印字符。这包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。

非打印字符

非打印字符也可以是正则表达式的组成部分。包括并不限于\n 换行符,\r 回车符等

非打印字符 ----- 功能 ------
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。
\f 匹配一个换页符。等价于 \x0c 和 \cL。
\n 匹配一个换行符。等价于 \x0a 和 \cJ。
\r 匹配一个回车符。等价于 \x0d 和 \cM。
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于 \x09 和 \cI。
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。

元字符

元字符,也就是具有特殊功能和意义的字符

特别字符 描述
$ 匹配输入字符串的结尾位置。要匹配 $ 字符本身,请使用 $
( ) 标记一个子表达式的开始和结束位置。要匹配这些字符,请使用 ( 和 )
* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 *
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 +
. 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 .
[ 标记一个中括号表达式的开始。要匹配 [,请使用 [
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 ?
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, 'n' 匹配字符 'n'。'\n' 匹配换行符。序列 '\' 匹配 "",而 '(' 则匹配 "("
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 ^
{ 标记限定符表达式的开始。要匹配 {,请使用 {
定位符
^ 匹配输入字符串开始的位置
$ 匹配输入字符串结尾的位置
非打印字符
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符
  • <.> 点字符表示一个字符,但是也分放在哪
    <.>放在外面表示任意一个字符,中括号内的<.>仅仅表示字符<.>

  • [#.] 放在中括号内,表示匹配中括号内任意一个字符。
    []中括号内是多个取一个的意思
[06:58:22 root@C8-3-55 ~]#ls /etc/ | grep 'rc' ##匹配/etc/目录下包含rc字段的文件
bashrc
csh.cshrc
inputrc
nanorc
pinforc
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
screenrc
vimrc
virc
wgetrc
[07:00:05 root@C8-3-55 ~]#ls /etc/ | grep 'rc[0-6]' ##匹配/etc/目录下包含rc字段和0-6中任意一个数字的文件
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
[07:00:21 root@C8-3-55 ~]#ls /etc/ | grep 'rc[.0-6]' ####匹配/etc/目录下包含rc字段的文件<.>字段或者0-6中任意一个数字的文件
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
[07:03:38 root@C8-3-55 ~]#touch /etc/rc
[07:05:39 root@C8-3-55 ~]#ls /etc/ | grep 'rc'. ##匹配rc开头且之后有任意一个字符这样字段的文件,rc文件不满足,因为字段是3个字符。
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
[07:05:51 root@C8-3-55 ~]#ls /etc/ | grep .'rc' ##匹配rc结尾且前面至少有一个字符的文件。rc文件不满足,因为字段是3个字符。
bashrc
csh.cshrc
inputrc
nanorc
pinforc
screenrc
vimrc
virc
wgetrc

  • ^ 脱字符 在中括号外边表示匹配开始位置,在中括号里边表示取反
    匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。
[07:22:21 root@C8-3-55 ~]#ls /etc/ | grep ^r
rc
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
rc.d
rc.local
redhat-release
resolv.conf
rhsm
rpc
rpm
rsyslog.conf
rsyslog.d
rwtab.d
[07:24:45 root@C8-3-55 ~]#ls /etc/ | grep [^r]
[07:24:58 root@C8-3-55 ~]#ls /etc/ | grep '[^r]'
adjtime
aliases
alternatives
anacrontab
asound.conf
at.deny
audit
authselect
bash_completion.d
bashrc
bindresvport.blacklist
binfmt.d
centos-release
centos-release-upstream
……
  • [^r]表示除去r以外的其他任意字符,行内有其他字符,所以还是会匹配到。

但是如果这一行全是r,就不会被匹配到了

[07:40:13 root@C8-3-55 ~]#echo araa brbb crcc rrrr r | tr ' ' '\n' | grep '[^r]
araa
brbb
crcc

匹配次数

通配符没有匹配次数的写法,正则表达式有。

    • 在正则表达式中表示某个字符出现的次数
  • .* 在正则表达式中表示任意字符
  • ? 在正则表达式中表示前面的字符出现0或1次,可有可无
  • + 在正则表达式中表示前面的字符出现大于1次
  • {n} 在正则表达式中表示前面的字符出现n次
  • {m,n} 在正则表达式中表示前面的字符出现的次数介于m,n之间
  • {m,} 在正则表达式中表示前面的字符出现的次数大于等于m
  • {,n} 在正则表达式中表示前面的字符出现的次数小于等于n

锚定位置

  • ^ 脱字符表示行首
[08:50:06 root@C8-3-55 ~]#grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
[09:14:20 root@C8-3-55 ~]#grep "^root" /etc/passwd
root:x:0:0:root:/root:/bin/bash
  • $ 美元表示行尾
[09:16:05 root@C8-3-55 ~]#grep "nologin$" /etc/passwd | tail -5
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
mysql:x:27:27:MySQL Server:/var/lib/mysql:/sbin/nologin
nginx:x:990:986:Nginx web server:/var/lib/nginx:/sbin/nologin
rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin
pipewire:x:989:985:PipeWire System Daemon:/var/run/pipewire:/sbin/nologin
  • ^$ 表示空行
  • [1]*$ 表示空白行

正则中的单词由且仅由数字、字母、下划线组成

  • < 或 \b 用于表示单词的词首
  • > 或 \b 用于表示单词的词尾
  • <PATTERN> 匹配整个单词

分组

  • () 将多个字符捆绑在一起,当作一个整体处理,如: (root)+
  • 后向引用
[09:49:07 root@C8-3-55 ~]#echo abc123abc abc123adc abc12345abc | tr " " "\n" | grep '\(abc\).*'
abc123abc
abc123adc
abc12345abc
[09:49:15 root@C8-3-55 ~]#echo abc123abc abc123adc abc12345abc | tr " " "\n" | grep '\(abc\).*\1'
abc123abc
abc12345abc

实例

  • 查看并统计 /etc/ssh/sshd_config文件中除去空行和#号开头的行的行数
[05:13:30 root@C8-3-55 ~]#grep -vn "^$\|^#" /etc/ssh/sshd_config
22:HostKey /etc/ssh/ssh_host_rsa_key
23:HostKey /etc/ssh/ssh_host_ecdsa_key
24:HostKey /etc/ssh/ssh_host_ed25519_key
40:SyslogFacility AUTHPRIV
46:PermitRootLogin yes
55:AuthorizedKeysFile   .ssh/authorized_keys
73:PasswordAuthentication yes
77:ChallengeResponseAuthentication no
87:GSSAPIAuthentication yes
88:GSSAPICleanupCredentials no
104:UsePAM yes
109:X11Forwarding yes
116:PrintMotd no
135:AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
136:AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
137:AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
138:AcceptEnv XMODIFIERS
141:Subsystem   sftp    /usr/libexec/openssh/sftp-server
[05:13:52 root@C8-3-55 ~]#grep -vn "^$\|^#" /etc/ssh/sshd_config | wc -l
18
  • 查找passwd文件包括.ot 的字符

通配符只能匹配文件名,不能匹配文件的内容

正则表达式中,元字符<.>的功能类似于通配符中<?>,匹配除换行符 \n 之外的任何单字符

[05:17:36 root@C8-3-55 ~]#grep ?ot /etc/passwd
[05:18:20 root@C8-3-55 ~]#grep [?]ot /etc/passwd
[05:18:28 root@C8-3-55 ~]#grep *ot /etc/passwd
[05:15:19 root@C8-3-55 ~]#grep .ot /etc/passwd ##匹配包含ot结尾字段的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
setroubleshoot:x:995:992::/var/lib/setroubleshoot:/sbin/nologin

[05:20:35 root@C8-3-55 ~]#grep r..t /etc/passwd ##匹配包含r开头,中间两个字符t结尾的字段的行
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
clevis:x:994:990:Clevis Decryption Framework unprivileged user:/var/cache/clevis:/sbin/nologin
rget1:x:8891:8891::/home/rget1:/bin/bash

  1. [:space:] ↩︎

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多