【计理01组06号】正则表达式基础入门

编程

博客推行版本更新,成果积累制度,已经写过的博客还会再次更新,不断地琢磨,高质量高数量都是要追求的,工匠精神是学习必不可少的精神。因此,大家有何建议欢迎在评论区踊跃发言,你们的支持是我最大的动力,你们敢投,我就敢肝

正则表达式介绍与基础

正则表达式(Regular Expression)是一个定义搜索模式的字符序列。

在做文字处理或编写程序时,若需要用到查找、替换等功能时,可以使用正则表达式来简单便捷地完成目标。

简单而言,正则表达式通过使用一些特殊符号,使得使用者可以方便轻松地实现查找、删除、替换等功能。

Vi 中经常会使用到正则表达式,为了充分发挥 shell 编程的威力,Linux 使用者需要精通正则表达式。

首先是正则表达式的特殊符号:

[:alnum:]代表英文大小写字母及数字 [:alpha:]代表英文大小写字母 [:blank:]代表空格和 tab 键 [:cntrl:]键盘上的控制按键,如 CR,LF,TAB,DEL [:digit:]代表数字 [:graph:]代表空白字符以外的其他 [:lower:]小写字母 [:print:]可以被打印出来的任何字符 [:punct:]代表标点符号 [:upper:]代表大写字母 [:space:]任何会产生空白的字符如空格,tab,CR 等 [:xdigit:]代表 16 进位的数字类型

特殊符号实例

在 WebIDE 中使用 touch 命令或图形界面新建一个 .txt 文件并将下文中的文本内容复制进去。

touch regular_express.txt

也可以使用 wget 指令从本节开头的实验环境说明处下载,这两种方式取得的文件是一样的。

文本内容为:

"Open Source" is a good mechanism to develop programs. apple is my favorite food. Football game is not use feet only. this dress doesn"t fit me. However, this dress is about $ 3183 dollars. GNU is free air not free beer. Her hair is very beauty. I can"t finish the test. Oh! The soup taste good. motorcycle is cheap than car. This window is clear. the symbol "*" is represented as start. Oh!My god! The gd software is a library for drafting programs. You are the best is mean you are the no. 1. The world <Happy> is the same with "glad". I like dog. google is the best tools for search keyword. goooooogle yes! go! go! Let"s go. # I am VBird

使用特殊符号查找小写字母:

grep -n "[[:lower:]]" regular_express.txt

红色为匹配成功的字符。

使用特殊符号查找数字:

grep -n "[[:digit:]]" regular_express.txt

grep命令与正则表达式

查找特定字符串

参数说明:

  • -a :以 text 档案的方式搜寻 binary 档案数据
  • -c :计算找到 "搜寻字符串" 的次数

  • -i :忽略大小写的不同,所以大小写视为相同
  • -n :顺便输出行号

  • -v :反向选择,亦即显示没有 "搜寻字符串" 内容的行

grep -n "the" regular_express.txt grep -in"the" regular_express.txt

反向查找,当该行没有字符串"the"时才显示在屏幕上。

grep -vn "the" regular_express.txt

字符组匹配

[ ]可以用来查找字符组。

值得注意的是,无论[ ]中包含多少个字符,它都只代表一个字符。比如说,我们想要查找tast或者test这两个字符串,注意到二者的拼写大部分相同,都是t?st的形式,故此时可以使用[ ]进行查找:

grep -n "t[ae]st" regular_express.txt

字符组支持使用连字符-来表示一个范围。当-前后构成范围时,要求前面字符的码位小于后面字符的码位。

[^]为反向选择字符组,用于排除后面的字符,使用方式为[^...]

需要注意[^]与参数-v的区别,尽管二者都表示反向选择,但是如果包含有反向选择的字符的行含有其他字符的话,[^]仍会输出该行,而-v则只会输出不含有反向选择的字符的行。

下面给出一些应用示例:

[abc] :表示 “a” 或 “b” 或 “c” [0-9] :表示 0~9 中任意一个数字,等价于 [0123456789] [u4e00-u9fa5] :表示任意一个汉字 [^a1<] :表示除 “a”、“1”、“<” 外的其它任意一个字符 [^a-z] :表示除小写字母外的任意一个字符

使用-[^]查找Xoo形式的字符串,要求oo之前不能包含小写字母:

grep -n "[^a-z]oo" regular_express.txt

回忆前一节所提到的正则表达式特殊符号,[:lower:]表示小写字母,因此也可以使用

grep -n "[^[:lower:]]oo" regular_express.txt

这两者是等价的,但是可以看出,使用[a-z]来表示小写字母明显更加便捷,也更加灵活。

查找字符oog

grep -n "oog" regular_express.txt

如果我不想要oog字符前面有 g,则使用[^g]oog

grep -n "[^g]oog" regular_express.txt

同理,若不想让字符oog前面为 g 或者 o,则使用[^go]oog

grep -n "[^go]oog" regular_express.txt

其中

grep -n "[^go]oog" regular_express.txt

返回结果为空,表示没有匹配到符合要求的字符串。

行首符 ^ 与行尾符 $

在第一个实验中,我们使用

grep -n "the" regular_express.txt

查找含有the的字符串,如果你只想查找行首为the的字符行,则使用以下命令:

grep -n "^the" regular_express.txt

查找行首为大写字母的所有行:

grep -n "^[A-Z]" regular_express.txt

注意行首符^和反向选择[^]的区别,^[A-Z]表示以大写字母开头。[^A-Z]表示除了大写字母 A-Z 的所有字符。

行尾符$的用法与行首符类似。

查找以字母 d 结尾的行:

grep -n "d$" regular_express.txt

这里有一个小技巧,将行首符与行尾符连用,可以用来查找空行:

grep -n "^$" regular_express.txt

应用实例

查看/etc/insserv.conf文档

^$: 过滤掉空白行

^#: 过滤掉注释行(以#号开头)

cat -n /etc/insserv.conf grep -v "^$" /etc/insserv.conf | grep -v "^#"

任意一个字符 . 与重复字符 *

查找a?ou?类型的字符:

grep -n "a.ou." regular_express.txt

其中小数点表示任意一个字符,一个小数点只能表示一个未知字符。

*(星号):代表重复前面 0 个或者多个字符。 e*: 表示具有空字符或者一个以上 e 字符。 ee*,表示前面的第一个 e 字符必须存在。第二个 e 则可以是 0 个或者多个 e 字符。 eee*,表示前面两个 e 字符必须存在。第三个 e 则可以是 0 个或者多个 e 字符。 ee*e :表示前面的第一个与第三个 e 字符必须存在。第二个 e 则可以是 0 个或者多个 e 字符。

下面的第一条命令与第二条命令由于允许存在空字符,所以会打印所有文本。

grep -n "e*" regular_express.txt grep -n "@*" regular_express.txt grep -n "eee*" regular_express.txt

限定连续字符范围 { }

{ }可限制一个范围区间内的重复字符数。如果现在要求找出存在连续的两个 o 字符的字符串,根据前面所学的知识,我们可以使用:

grep -n "ooo*" regular_express.txt

另一种方式是使用{ }。由于{}在 shell 中有特殊意义,故在使用时需要用到转义字符

查找连续的两个 o 字符:

grep -n "o{2}" regular_express.txt

查找 g 后面接 2 到 5 个 o,然后再接 g 的字符串:

grep -n "go{2,5}g" regular_express.txt

总结:

^word 表示待搜寻的字符串(word)在行首 word$ 表示待搜寻的字符串(word)在行尾 .(小数点) 表示 1 个任意字符 表示转义字符,在特殊字符前加 会将特殊字符意义去除 * 表示重复 0 到无穷多个前一个 RE(正则表达式)字符 [list] 表示搜索含有 l,i,s,t 任意字符的字符串 [n1-n2] 表示搜索指定的字符串范围,例如 [0-9] [a-z] [A-Z] 等 [^list] 表示反向字符串的范围,例如 [^0-9] 表示非数字字符,[^A-Z] 表示非大写字符范围 {n,m} 表示找出 n 到 m 个前一个 RE 字符 {n,} 表示 n 个以上的前一个 RE 字符

sed命令与正则表达式

sed 是非交互式的编辑器。它不会修改文件,除非使用 shell 重定向来保存结果。默认情况下,所有的输出行都会被打印到屏幕上。

sed 编辑器逐行处理文件(或输入),并将结果打印到屏幕上。

具体过程如下:首先 sed 把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上。

sed 每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示。处理完输入文件的最后一行后,sed 便结束运行。sed 把每一行都存在临时缓冲区中,对这个副本进行编辑,所以直接使用不会修改原文件内容。

如果要修改原文件,需要添加 -i 选项。

输出文件内容

将 regular_express.txt 的内容列出并打印行号,并将 2-5 行删除显示:

nl regular_express.txt | sed "2,5d"

2,5d表示删除 2~5 行,d 即为 delete。

同理,删除第 2 行:

nl regular_express.txt | sed "2d"

删除第三行到最后一行,$表示定位到最后一行:

nl regular_express.txt | sed "3,$d"

使用-i在原文件中删除第 1 行:(注意:该指令会修改原文件)

sed -i "1d" regular_express.txt

使用 a 和 i 新增输出

在第二行后添加字符串 test:

nl regular_express.txt | sed "2a test"

在第二行前添加字符串 test:

nl regular_express.txt | sed "2i test"

在第二行后添加两行 test,

表示换行符:

nl regular_express.txt | sed "2a test

test"

行内容替换

将 2-5 行的内容替换为No 2-5 number,c 为替换内容选项:

nl regular_express.txt | sed "2,5c No 2-5 number"

输出指定行

输出 regular_express.txt 的第 5-7 行,其中-n为安静模式选项,我们在前面的章节中已经介绍过。

执行以下两条命令可以明显看出区别:

nl regular_express.txt |sed -n "5,7p" nl regular_express.txt |sed "5,7p"

字符串替换

格式为:sed "s/lodstr/newstr/g"

来看一个实例。首先查看本机 IP 地址:

ifconfig eth0

字段inet 地址:192.168.x.x即为本机的 IP 地址,这是经由 NAT 转换后分配的内网 IP 地址,在此不做展开。

之后使用grep指令在ifconfig eth0的结果中查找inet,并打印至终端:

ifconfig eth0 | grep "inet"

可以使用字符串替换功能将 IP 前面的部分予以删除,按照思路,也就是将inet 地址:替换为空字符串,可以简单写成:

ifconfig eth0 | grep "inet "| sed "s/inet 地址://g"

(注意中文字符不能直接复制,需要自己在终端输入)

但正则表达式在实际应用中可以非常灵活,回想一下我们在前两节所学的关于正则表达式的知识(忘了也不要紧,可以随时返回查看)。

.表示任意一个字符,*表示重复字符,{ }表示限定连续字符范围,所以正则表达式也可以写成:

ifconfig eth0 |grep "inet "| sed "s/.inet...://g"# 或者 ifconfig eth0 |grep "inet "| sed "s/.{0,9}://"

表达式的写法并不唯一,在此也并未全部列出,大家亦可自行尝试使用其他写法,欢迎在评论区中讨论。

将 IP 后面的部分删除:

/sbin/ifconfig eth0 |grep "inet "| sed "s/.inet...://g"| sed "s/..:.*$//g" /sbin/ifconfig eth0 |grep "inet "| sed "s/.inet...://g"| sed "s/.{0,3}:.*$//g"

上述指令是比较复杂的正则表达式运用,熟悉正则表达式后可以明显地简化指令,简单便捷地完成文件的查询、修改等任务。

正则表达式扩展应用

使用扩展正则表达式 egrep

首先来看一条前面章节学习过的用来去除空白行和注释行的指令:

grep -v "^$" regular_express.txt |grep -v "^#"

可见,通常的grep指令需要使用两次管线命令。那么如果使用扩展正则表达式,则可以简化为:

egrep -v "^$|^#" regular_express.txt

利用支持扩展正则表达式的egrep与特殊字符|的组合功能来间隔两组字符串,如此一来,可以极大地化简指令。

此外,也可以使用 grep -E 来使用扩展正则表达式,不过一般更建议直接使用 egrepgrep -Eegrep 之间类似命令别名的关系。

扩展规则(一)

回忆一下,在非扩展正则表达式中,我们使用*来表示任意个重复字符(零至无穷多个):

grep -n "goo*d" regular_express.txt

在扩展正则表达式中,则可以进一步细分为一个或一个以上零个或一个字符:

+表示重复一个或一个以上的前一个字符

egrep -n "go+d" regular_express.txt

?表示重复零个或一个的前一个字符

egrep -n "go?d" regular_express.txt

执行上述三条指令,比较三者的不同。

扩展规则(二)

|表示用或(or)的方式找出数个字符串

查找 gd 或 good:

egrep -n "gd|good" regular_express.txt

()表示找出组字符串

查找 glad 或 good,注意到由于二者存在重复字母,所以可以将其合并:

egrep -n "g(la|oo)d" regular_express.txt

()+多个重复群组判别

查找开头是 A 结尾是 C 中间有一个以上的xyzxz字符串:

echo"AxyzxyzxyzxyzC"|egrep "A(xyz)+C"echo"AxyzxyzxyzxyzC"|egrep "A(xz)+C"

结果显示A(xyz)+C可以匹配,A(xz)+C没有匹配项。

在黑夜里梦想着光,心中覆盖悲伤,在悲伤里忍受孤独,空守一丝温暖。

我的泪水是无底深海,对你的爱已无言,相信无尽的力量,那是真爱永在。

我的信仰是无底深海,澎湃着心中火焰,燃烧无尽的力量,那是忠诚永在

以上是 【计理01组06号】正则表达式基础入门 的全部内容, 来源链接: utcz.com/z/520219.html

回到顶部