正则表达式

  • 一、什么是正则表达式
    • 1. 定义
    • 2. 正则表达式的类型
  • 二、 基本正则表达式(BRE模式)
    • 1.纯文本
    • 2.特殊字符
    • 3.锚字符
      • 3.1 锁定在行首
      • 3.2 锁定在行尾
      • 3.3 组合锚点
    • 4 点字符号
    • 5. 字符组
    • 6. 排除型字符组
    • 7. 区间
    • 8. 星号
      • 8.1 用法一
      • 8.2 用法二
      • 8.3 用法三
    • 9. 特殊的字符组
  • 三、 扩展正则表达式(ERE模式)
    • 1.问号
    • 2.加号
    • 3.花括号
    • 4.管道符号
    • 5.表达式分组

一、什么是正则表达式

1. 定义

正则表达式是你所定义的模式模板(pattern template),Linux工具可以用它来过滤文本。Linux工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉。

shell脚本中成功运用sed编辑器和gawk程序的关键在于熟练使用正则表达式。

正则表达式模式利用通配符来描述数据流中的一个或多个字符。Linux中有很多场景都可以使用通配符来描述不确定的数据。

比如ls命令中使用通配符列出文件和目录的例子

$ ls -al da*
-rw-r--r-- 1 rich rich 45 Nov 26 12:42 data
-rw-r--r-- 1 rich rich 25 Dec 4 12:40 data.tst
-rw-r--r-- 1 rich rich 180 Nov 26 12:42 data1
-rw-r--r-- 1 rich rich 45 Nov 26 12:44 data2
-rw-r--r-- 1 rich rich 73 Nov 27 12:31 data3
-rw-r--r-- 1 rich rich 79 Nov 28 14:01 data4
-rw-r--r-- 1 rich rich 187 Dec 4 09:45 datatest

2. 正则表达式的类型

使用正则表达式最大的问题在于有不止一种类型的正则表达式。Linux中的不同应用程序可能会用不同类型的正则表达式。这其中包括编程语言(Java、Perl和Python)、Linux实用工具(比如sed编辑器、gawk程序和grep工具)以及主流应用(比如MySQL和PostgreSQL数据库服务器)。

正则表达式是通过正则表达式引擎(regular expression engine)实现的。正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配。

在Linux中,有两种流行的正则表达式引擎:

  • POSIX基础正则表达式(basic regular expression,BRE)引擎
  • POSIX扩展正则表达式(extended regular expression,ERE)引擎

二、 基本正则表达式(BRE模式)

最基本的BRE模式是匹配数据流中的文本字符。

1.纯文本

下面的命令演示了在sed编辑器和gawk程序中用标准文本字符串来过滤数据。

$ echo "This is a test" | sed -n '/test/p'
This is a test
$ echo "This is a test" | sed -n '/trial/p'
$
$ echo "This is a test" | gawk '/test/{print $0}'
This is a test
$ echo "This is a test" | gawk '/trial/{print $0}'
$

第一个模式定义了一个单词test。sed编辑器和gawk程序脚本用它们各自的print命令打印出匹配该正则表达式模式的所有行。由于echo语句在文本字符串中包含了单词test,数据流文本能够匹配所定义的正则表达式模式,因此sed编辑器显示了该行。

第二个模式也定义了一个单词,这次是trial。因为echo语句文本字符串没包含该单词,所以正则表达式模式没有匹配,因此sed编辑器和gawk程序都没打印该行。

正则表达式的原则:

  • 正则表达式模式都区分大小写。
  • 你不用写出整个单词。只要定义的文本出现在数据流中,正则表达式就能够匹配。
  • 可以在正则表达式中使用空格和数字。

2.特殊字符

在正则表达式模式中使用文本字符时,有些事情值得注意。在正则表达式中定义文本字符时有一些特例。有些字符在正则表达式中有特别的含义。如果要在文本模式中使用这些字符,结果会超出你的意料。

正则表达式识别的特殊字符包括:

. * [ ] ^ $ { } \ + ? | ( )

记住不能在文本模式中单独使用这些字符。
如果要用某个特殊字符作为文本字符,就必须使用反斜线(\)转义。

3.锚字符

默认情况下,当指定一个正则表达式模式时,只要模式出现在数据流中的任何地方,它就能匹配。有两个特殊字符可以用来将模式锁定在数据流中的行首或行尾。

3.1 锁定在行首

脱字符(^)定义从数据流中文本行的行首开始的模式。如果模式出现在行首之外的位置,正则表达式模式则无法匹配。

要用脱字符,就必须将它放在正则表达式中指定的模式前面。

$ echo "The book store" | sed -n '/^
book/p'
$
$ echo "Books are great" | sed -n '/^
Book/p'
Books are great
$

脱字符会在每个由换行符决定的新数据行的行首检查模式。

$ cat data3
This is a test line.
this is another test line.
A line that tests this feature.
Yet more testing of this
$ sed -n '/^
this/p' data3
this is another test line.
$

只要模式出现在新行的行首,脱字符就能够发现它。
如果你将脱字符放到模式开头之外的其他位置,那么它就跟普通字符一样,不再是特殊字符了:

3.2 锁定在行尾

跟在行首查找模式相反的就是在行尾查找。特殊字符美元符($)定义了行尾锚点。将这个特殊字符放在文本模式之后来指明数据行必须以该文本模式结尾。

$ echo "This is a good book" | sed -n '/book$/p'
This is a good book
$ echo "This book is good" | sed -n '/book$/p'
$

3.3 组合锚点

在一些常见情况下,可以在同一行中将行首锚点和行尾锚点组合在一起使用。

$ cat data4
this is a test of using both anchors
I said this is a test
this is a test
I'm sure this is a test.
$ sed -n '/^
this is a test$/p' data4
this is a test
$

将两个锚点直接组合在一起,之间不加任何文本,这样过滤出数据流中的空白行。极其有用。

$ cat data5
This is one test line. This is another test line.
$ sed '/^
$/d' data5
This is one test line.
This is another test line.
$

定义的正则表达式模式会查找行首和行尾之间什么都没有的那些行。由于空白行在两个换行符之间没有文本,刚好匹配了正则表达式模式。sed编辑器用删除命令d来删除匹配该正则表达式模式的行,因此删除了文本中的所有空白行。这是从文档中删除空白行的有效方法。

4 点字符号

特殊字符点号用来匹配除换行符之外的任意单个字符。它必须匹配一个字符,如果在点号字符的位置没有字符,那么模式就不成立。

$ cat data6
This is a test of a line.
The cat is sleeping.
That is a very nice hat.
This test is at line four.
at ten o'clock we'll go home.
$ sed -n '/.at/p' data6
The cat is sleeping.
That is a very nice hat.
This test is at line four.
$

5. 字符组

点号特殊字符在匹配某个字符位置上的任意字符时很有用。但如果你想要限定待匹配的具体字符呢?在正则表达式中,这称为字符组。

使用方括号来定义一个字符组。方括号中包含所有你希望出现在该字符组中的字符。然后你可以在模式中使用整个组,就跟使用其他通配符一样。
下面是个创建字符组的例子。

$ sed -n '/[ch]at/p' data6
The cat is sleeping.
That is a very nice hat.
$

这里我们希望匹配的是含有单词cat 或hat的行。

在不太确定某个字符的大小写时,字符组会非常有用。

$ echo "Yes" | sed -n '/[Yy]es/p'
Yes
$ echo "yes" | sed -n '/[Yy]es/p'
yes
$

可以在单个表达式中用多个字符组。

$ echo "Yes" | sed -n '/[Yy][Ee][Ss]/p'
Yes
$ echo "yEs" | sed -n '/[Yy][Ee][Ss]/p'
yEs
$ echo "yeS" | sed -n '/[Yy][Ee][Ss]/p'
yeS
$

字符组不必只含有字母,也可以在其中使用数字。

字符组的一个极其常见的用法是解析拼错的单词,比如用户表单输入的数据。你可以创建正则表达式来接受数据中常见的拼写错误。

$ cat data9
I need to have some maintenence done on my car.
I'll pay that in a seperate invoice.
After I pay for the maintenance my car will be as good as new.
$ sed -n '
/maint[ea]n[ae]nce/p
/sep[ea]r[ea]te/p
' data9
I need to have some maintenence done on my car.
I'll pay that in a seperate invoice.
After I pay for the maintenance my car will be as good as new.
$

本例中的两个sed打印命令利用正则表达式字符组来帮助找到文本中拼错的单词maintenance和separate。同样的正则表达式模式也能匹配正确拼写的maintenance。

6. 排除型字符组

在正则表达式模式中,也可以反转字符组的作用。可以寻找组中没有的字符,而不是去寻找字符组中含有的字符。要这么做的话,只要在字符组的开头加个脱字符。

$ sed -n '/[^
ch]at/p' data6
This test is at line four.
$

通过排除型字符组,正则表达式模式会匹配c或h之外的任何字符以及文本模式。由于空格字符属于这个范围,它通过了模式匹配。但即使是排除,字符组仍然必须匹配一个字符,所以以at开头的行仍然未能匹配模式。

7. 区间

可以用单破折线符号在字符组中表示字符区间。正则表达式会包括此区间内的任意字符。适用于数字,字母。

$ cat data8
60633
46201
223001
4353
22203
$ sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data8
60633
46201
45902
$
$ sed -n '/[c-h]at/p' data6
The cat is sleeping.
That is a very nice hat.
$

8. 星号

在字符后面放置星号表明该字符必须在匹配模式的文本中出现0次或多次。

$ echo "ik" | sed -n '/ie*k/p'
ik
$ echo "iek" | sed -n '/ie*k/p'
iek
$ echo "ieek" | sed -n '/ie*k/p'
ieek
$ echo "ieeek" | sed -n '/ie*k/p'
ieeek
$ echo "ieeeek" | sed -n '/ie*k/p'
ieeeek
$

8.1 用法一

这个模式符号广泛用于处理有常见拼写错误或在不同语言中有拼写变化的单词。举个例子,如果需要写个可能用在美式或英式英语中的脚本,可以这么写:

$ echo "I'm getting a color TV" | sed -n '/colou*r/p'
I'm getting a color TV
$ echo "I'm getting a colour TV" | sed -n '/colou*r/p'
I'm getting a colour TV
$

模式中的u*表明字母u可能出现或不出现在匹配模式的文本中。类似地,如果你知道一个单词经常被拼错,你可以用星号来允许这种错误。

8.2 用法二

另一个方便的特性是将点号特殊字符和星号特殊字符组合起来。这个组合能够匹配任意数量的任意字符。它通常用在数据流中两个可能相邻或不相邻的文本字符串之间。

$ echo "this is a regular pattern expression" | sed -n '
> /regular.*expression/p'
this is a regular pattern expression
$

可以使用这个模式轻松查找可能出现在数据流中文本行内任意位置的多个单词。

8.3 用法三

星号还能用在字符组上。它允许指定可能在文本中出现多次的字符组或字符区间。

$ echo "bt" | sed -n '/b[ae]*t/p'
bt
$ echo "bat" | sed -n '/b[ae]*t/p'
bat
$ echo "bet" | sed -n '/b[ae]*t/p'
bet
$ echo "btt" | sed -n '/b[ae]*t/p'
btt
$
$ echo "baat" | sed -n '/b[ae]*t/p'
baat
$ echo "baaeeet" | sed -n '/b[ae]*t/p'
baaeeet
$ echo "baeeaeeat" | sed -n '/b[ae]*t/p'
baeeaeeat
$ echo "baakeeet" | sed -n '/b[ae]*t/p'
$

9. 特殊的字符组

除了定义自己的字符组外,BRE还包含了一些特殊的字符组,可用来匹配特定类型的字符。

三、 扩展正则表达式(ERE模式)

POSIX ERE模式包括了一些可供Linux应用和工具使用的额外符号。gawk程序能够识别ERE模式,但sed编辑器不能。

下面将介绍可用在gawk程序脚本中的较常见的ERE模式符号。

1.问号

问号类似于星号,不过有点细微的不同。问号表明前面的字符可以出现0次或1次,但只限于此。它不会匹配多次出现的字符。

$ echo "bt" | gawk '/be?t/{print $0}'
bt
$ echo "bet" | gawk '/be?t/{print $0}'
bet
$ echo "beet" | gawk '/be?t/{print $0}'
$
$ echo "beeet" | gawk '/be?t/{print $0}'
$

与星号一样,你可以将问号和字符组一起使用。

$ echo "bt" | gawk '/b[ae]?t/{print $0}'
bt
$ echo "bat" | gawk '/b[ae]?t/{print $0}'
bat
$ echo "bot" | gawk '/b[ae]?t/{print $0}'
$
$ echo "bet" | gawk '/b[ae]?t/{print $0}'
bet
$ echo "baet" | gawk '/b[ae]?t/{print $0}'
$
$ echo "beat" | gawk '/b[ae]?t/{print $0}'
$
$ echo "beet" | gawk '/b[ae]?t/{print $0}'
$

2.加号

加号是类似于星号的另一个模式符号,但跟问号也有不同。加号表明前面的字符可以出现1次或多次,但必须至少出现1次。如果该字符没有出现,那么模式就不会匹配。

$ echo "beeet" | gawk '/be+t/{print $0}'
beeet
$ echo "beet" | gawk '/be+t/{print $0}'
beet
$ echo "bet" | gawk '/be+t/{print $0}'
bet
$ echo "bt" | gawk '/be+t/{print $0}'
$

3.花括号

ERE中的花括号允许你为可重复的正则表达式指定一个上限。这通常称为间隔(interval)。
可以用两种格式来指定区间。

  • m:正则表达式准确出现m次。
  • m, n:正则表达式至少出现m次,至多n次。

这个特性可以精确调整字符或字符集在模式中具体出现的次数。

默认情况下,gawk程序不会识别正则表达式间隔。必须指定gawk程序的–re- interval
命令行选项才能识别正则表达式间隔。

$ echo "bt" | gawk --re-interval '/be{1}t/{print $0}'
$
$ echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1}t/{print $0}'
$

通过指定间隔为1,限定了该字符在匹配模式的字符串中出现的次数。如果该字符出现多次,
模式匹配就不成立。

很多时候,同时指定下限和上限也很方便。

$ echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}'
$
$ echo "bet" | gawk --re-interval '/be{1,2}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}'
beet
$ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}'
$

在这个例子中,字符e可以出现1次或2次,这样模式就能匹配;否则,模式无法匹配。
间隔模式匹配同样适用于字符组。

4.管道符号

管道符号允许你在检查数据流时,用逻辑OR方式指定正则表达式引擎要用的两个或多个模式。如果任何一个模式匹配了数据流文本,文本就通过测试。如果没有模式匹配,则数据流文本匹配失败。

$ echo "The dog is asleep" | gawk '/cat|dog/{print $0}'
The dog is asleep
$ echo "The sheep is asleep" | gawk '/cat|dog/{print $0}'
$

这个例子会在数据流中查找正则表达式cat或dog。正则表达式和管道符号之间不能有空格,否则它们也会被认为是正则表达式模式的一部分。

5.表达式分组

正则表达式模式也可以用圆括号进行分组。当你将正则表达式模式分组时,该组会被视为一个标准字符。可以像对普通字符一样给该组使用特殊字符。举个例子:

$ echo "Sat" | gawk '/Sat(urday)?/{print $0}'
Sat
$ echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
Saturday
$

结尾的urday分组以及问号,使得模式能够匹配完整的Saturday或缩写Sat。
将分组和管道符号一起使用来创建可能的模式匹配组是很常见的做法。

Linux正则表达式使用方法详解相关推荐

  1. java perl5compiler,Java中正则表达式使用方法详解(四)

    3.2 HTML处理实例一 下面一个任务是分析HTML页面内FONT标记的所有属性.HTML页面内典型的FONT标记如下所示 程序将按照如下形式,输出每一个FONT标记的属性 在这种情况下,我建议你使 ...

  2. 小何讲进程: 编写Linux守护进程方法详解

    守护进程概述 守护进程,也就是通常所说的Daemon进程,是Linux中的后台服务进程. 它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些事件的发生. 守护进程常常在 ...

  3. Linux帮助使用方法详解

    首先要弄明白一点,个人认为Linux里的帮助不是为了让我们使用它学习新知识,而是帮助我们复苏记忆.    有多种方式的帮助如下:           help     --help 或者 -h     ...

  4. Linux 根目录满了 linux根目录扩容方法 详解!!!

    CentOS 7根目录扩容方法 最近公司测试服务器根目录满了,便有同事网上找了教程进行扩容,但是由于找的教程不够严谨 导致扩容失败,还丢失了一部分文件,所以这里详细说明一下方法. 方法流程说明: 1. ...

  5. linux find文件,并复制,通过find命令寻找文件并拷贝到一个指定目录方法详解

    有这样的一个需求,需要将一部分符合条件的文件从一个目录拷贝到另一个目录中,可以通过使用find命令从源目录查找到符合条件的文件然后使用cp命令拷贝到目标目录 将通过find命令找到的文件拷贝到一个新的 ...

  6. Linux crontab定时任务配置方法(详解)

    id="BAIDU_DUP_fp_iframe" src="https://pos.baidu.com/wh/o.htm?ltr="> 脚本之家 服务器常 ...

  7. linux oracle 用户创建,LINUX下Oracle数据库用户创建方法详解

    本文实例分析了LINUX下Oracle数据库用户创建方法.分享给大家供大家参考,具体如下: 1)登录linux,以oracle用户登录(如果是root用户登录的,登录后用 su - oracle命令切 ...

  8. Linux中history历史命令使用方法详解

    在/etc/profile里添加如下:#History export HISTTIMEFORMAT="[%F %T]" HISTDIR=/home/common/.hist if ...

  9. python定时任务crontab_【Python】Linux crontab定时任务配置方法(详解)

    CRONTAB概念/介绍 crontab命令用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于"crontab"文件中,以供之后读取和执行. cron 系统调度 ...

最新文章

  1. 微信小程序发红包功能实现,附效果图加讲解。
  2. 云原生如此重要,可惜80%的人都不知道
  3. pytorch 多进程队列
  4. python程序改错题字符统计_Python练习题 012:字符统计
  5. java框架学习日志-2
  6. 2019年,瑞云渲染做了这些事……
  7. android 读取文件内容,Android读写文件 获取文件并读取写入数据
  8. struts2 result随笔
  9. 探寻安全管理平台(SOC)项目的关键成功因素(4)
  10. Android 四大组件学习之Service四
  11. 网络安全实验七:防火墙实验
  12. App测试查看日志(详细)
  13. linux下安装sg11,Linux安装SG11加密扩展组件教程
  14. FaceBook流程到底应该如何?
  15. 2011-11-27神马浮云的一天
  16. 古筝四秀 宋婷婷、付娜、常静、吴莉
  17. 挑战与机遇,RPA人才为何如此抢手?
  18. 数据结构与算法【Java】05---排序算法总结
  19. 数据库实验一:数据库与数据表定义(1)—— 数据库相关操作
  20. 与日俱进,在 Go 1.20 中这种高效转换的方式又变了

热门文章

  1. 更改Oracle默认端口8080(亲测)
  2. 微软发布了 97 个漏洞的补丁,包括主动勒索软件漏洞
  3. python考试编程题九道
  4. Unity3D优化技巧系列二
  5. python就业前景不好_Python就业前景好不好?为什么学完Python找不到工作?
  6. 鼠标悬浮事件 -jQuery hover()方法(layer.js)(layer.tips)
  7. mysql字符集编码和排序规则
  8. Android 系统提供的主题
  9. [C语言]猴子吃桃问题 猴子第一天摘下若干个桃子,每天都吃了前一天剩下的一半零一个,到第10天早上想再吃的时候,就剩下一个桃子. 求第一天共摘多少个桃子?
  10. log4j与logback冲突的解决与思考