正则表达式

本文详细介绍了正则表达式在Linux Shell脚本中的使用,包括正则表达式的定义、类型、特殊字符、BRE模式、ERE模式以及在实际场景中的应用,如文件计数、电话号码验证和邮件地址解析。通过实例展示了如何利用正则表达式进行文本过滤和数据验证。
摘要由CSDN通过智能技术生成

       在shell脚本中成功运用sed编辑器和gawk程序的关键在于熟练使用正则表达式。这可不是件简单的事,从大量数据中过滤出特定数据可能会(而且经常会)很复杂。

一.什么是正则表达式
       理解正则表达式的第一步在于弄清他们到底是什么。

1.定义
       正则表达式是你所定义的模式模板,Linux工具可以用它来过滤文本。linux工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配,如果数据匹配模式,他就会被接受并进一步处理;如果数据不匹配模式,他就会被过滤掉。图20-1描述了这个过程。
在这里插入图片描述
       正则表达式模式利用通配符来描述数据流中的一个或多个字符。Linux中有很多场景都可以使用通配符来描述不确定的数据。
       星号通配符允许你只列出满足特定条件的文件,例如:

$ 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 
$

       da*参数会让ls命令只列出名字以da开头的文件。文件名中da之后可以有任意多个字符(包括什么也没有)。ls命令会读取目录中所有文件的信息,但只显示跟通配符匹配的文件的信息。
       正则表达式通配符模式的工作原理与之类似。正则表达式含有文本或特殊字符,为sed编辑器和gawk程序定义了一个匹配数据时采用的模板。可以在正则表达式中使用不同的特殊字符来定义特定的数据过滤模式。

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)引擎
       大多数Linux工具都至少符合POSIX BRE引擎规范,能够识别该规范定义的所有模式符号。遗憾的是,有些工具(比如sed编辑器)只符合了BRE引擎规范的子集。这是出于速度方面的考虑导致的,因为sed编辑器希望尽可能快地处理数据流中的文本。
       POSIX BRE尽情同城出现在依赖正则表达式进行文本过滤的编程语言中。它为常见模式提供了高级模式符号和特殊符号,比如匹配数字、单词以及按字母排序的字符。gawk程序使用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程序都没打印该行。
       你可能注意到了,正则表达式并不关心模式在数据流中的位置。他也不关心模式出现了多少次。一旦正则表达式匹配了文本字符串中任意位置上的模式,他就会将该字符串传回Linux工具。
       关键在于正则将正则表达式模式匹配到数据流文本上。重要的是记住正则表达式对匹配的模式非常挑剔。第一条原则就是:正则表达式模式都区分大小写。这意味着他们只会匹配大小写也相符的模式。

$ echo "This is a test" | sed -n '/this/p'
$
$ echo "This is a test" | sed -n '/This/p'
This is a test
$

       第一次尝试没能匹配成功,因为this在字符传中并不都是小写,第二次尝试在模式中使用大写字母,所以能正常工作。
       在正则表达式中,你不用写出整个单词。只要定义的文本出现在数据流中,正则表达式就能够匹配。

$ echo "The books are expensive" | sed -n '/book/p'
The books are expensive
$

       尽管数据流中的文本是books,但数据中含有正则表达式book,因此正则表达式末世跟数据匹配。当然,反之表达式就不成立了。

$ echo "The book is expensive" | sed -n '/books/p'
$

       完整的正则表达式文本并未在数据流中出现,因此匹配失败,sed编辑器不会显示任何文本。
       你也不用局限于在正则表达式中只用单个文本单词,可以在正则表达式中使用空格和数字。

$ echo "This is line number 1" | sed -n '/ber 1/p'
This is line number 1
$

       在正则表达式中,空格和其他的字符并没有什么区别。

$ echo "This is line number1" | sed -n '/ber 1/p'
$

       如果你在正则表达式中定义了空格,那么他必须出现在数据流中。甚至可以创建匹配多个连续空格的正则表达式模式。

$ cat data1
This is a normal line of text.
This is a line with too many spaces.
$ sed -n '/ /p' data1
This is a line with too many spaces.
$

       单词间有两个空格的行匹配正则表达式模式。这是用来查看文本文件中空格问题的好办法。

2.特殊字符
       在震泽表达式中使用文本字符时,有些事情值得注意。在正则表达式中定义文本字符时有一些特例。有些字符在正则表达式中有特别的含义。如果要在文本模式中使用这些字符,结果会超出你的意料。
       正则表达式识别的特殊字符包括:
       .*[]^${}\+?|()
       随着本章内容的继续,你会了解到这些特殊字符在正则表达式中有何用处。不过现在只要记住不能在文本模式中单独使用这些字符就行了。
       如果要用某个特殊字符作为文本字符,就必须转义。在转义特殊字符时,你需要在它前面加一个特殊字符来告诉正则表达式引擎应该将接下来的字符当作普通的文本字符。这个特殊字符就是反斜线(\)。
       举个例子,如果要查找文本中的美元符,只要在它前面加个反斜线。

$ cat data2
The cost is $4.00
$ sed -n '/\$/p' data2
The cost is $4.00
$

       由于反斜线是特殊字符,如果要在正则表达式模式中使用它,你必须对其转义,这样就产生了两个反斜线。

$ echo "\ is a special character" | sed -n '/\\/p'
\ is a special character
$

       最终,尽管正斜线不是正则表达式的特殊字符,但如果它出现在sed编辑器或gawk程序的正则表达式中,你就会得到一个错误。

$ echo "3 / 2" | sed -n '///p'
sed: -e expression #1, char 2: No previous regular expression
$

       要使用正斜线,也需要进行转义。

$ echo "3 / 2" | sed -n '/\//p'
3 / 2
$

       现在sed编辑器能正确解释正则表达式模式了,一切都很顺利。

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.
$

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

$ echo "This ^ is a test" | sed -n 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值