《正则表达式必知必会》读书笔记2

. 使用元字符

1. 对特殊字符进行转义

元字符是一些在正则表达式里有着特殊含义的字符,所以这些字符就无法用来代表它们本身。任何一个元字符都可以通过给它加上一个反斜杠字符/ 作为前缀的办法来转义。

2. 匹配空白字符

元字符大致可以分为两种:一种是用来匹配文本的(比如. ),另一种是正则表达式的语法要求的(比如[ 和] )。

在进行正则表达式搜索的时候,我们经常会遇到需要对原始文本里的非打印空白字符进行匹配,或者我们需要把换行符找出来,这类字符很难被直接输入到一个正则表达式中,但我们可以使用下列的特殊字符来输入:

                                     空白元字符

元字符                           说明

[/b]                  回退(并删除)一个字符( backspace 键)

/f                    换页符

/n                    换行符

/r                    回车符

/t                    制表符( Tab 键)

/v                    垂直制表符

注: /r/n 是 windows 所使用的文本行结束标签。 Unix 和 Linux 系统只使用一个换行符结束一个文本行;换句话说,在 Unix/Linux 系统上匹配空白行只使用 /n/n 即可,不需要加上 /r 。

3. 匹配特定的字符类别

一些常用的字符集合可以用特殊的元字符来代替。这些元字符匹配的是某一类别的字符(术语称之为“字符类”)。

( 1 )匹配数字

                 数字元字符

元字符         说明                        

/d          任何一个数字字符(等价于[ 0-9 ])

/D          任何一个非数字字符(等价于[ ^0-9 ])

例子:

文本

xyf[1]

xyf[5]

xyf[a]

正则表达式: xyf/[/d/]

结果:

Matches Found: 2

Match

Position

Length

xyf[1]

0

6

xyf[5]

7

6

( 2 )匹配字母和数字(与非字母和数字)

                 字母数字元字符

元字符                说明

/w              任何一个字母数字字符(大小写均可)或下划线字符(等价于[ a-zA-Z0-9_ ])

/W              任何一个非字母数字和非下划线字符 ( 等价于 [^a-zA-Z0-9_])

( 3 )匹配空白字符(非空白字符)

                   空白字符元字符

元字符           说明

/s            任何一个空白字符(等价于 [/f/n/r/t/v] )

/S            任何一个非空白字符(等价于 [^/f/n/r/t/v] )

注意:用来匹配退格字符的 [/b] 元字符是一个特例:它不在元字符 /s 的覆盖范围内,当然也没排除在类元字符 /S 的覆盖范围外。

( 4 )匹配十六进制或八进制

使用十六进制值

在正则表达式里,十六进制数值要用前缀 /x 来给出。比如, /x0A 对应于 ASCII 字符 10 (换行符),其效果等价于 /n 。

使用八进制值

在正则表达式中,八进制数值要用前缀 /0 来给出,数值本身可以是两位或者三位。比如 /011 对应于 ASCII 字符 9 (制表符),其效果等价于 /t 。

4. 使用 POSIX 字符类

(省略)

. 重复匹配

1. 匹配一个或多个字符

要想匹配同一个字符或字符集合的多次重复,只要简单地给这个字符或字符集合加上一个 + 字符作为后缀就行了。比如, a 匹配 a 本身, a+ 将匹配一个或多个连续出现的 a 。类似地, [0-9] 匹配任意单个数字, [0-9]+ 将匹配一个或多个连续的数字。

例子:

文本

fnoiaqowoe qwjeqw

xyf@shu.edu.cn aoidahoiqw

daidoqwideqw

正则表达式: /w+@[/w.]+/w

结果:

Matches Found: 1

Match

Position

Length

xyf@shu.edu.cn

18

14


2. 匹配零个或多个字符

+ 匹配一个或者多个字符。但不匹配零个字符。如果你想匹配一个可有可无的字符,可用元字符*

3. 匹配零个或一个字符

元字符 ? 只能匹配一个字符(或字符集合)的零次或一次出现,最多不超过一次。如果需要在一段文本里匹配某个特定的字符(或字符集合)而该字符可能出现,也可能不出现,?无疑是最佳的选择。

例子:

文本

welcome to http://www.shu.edu.cn/ and https://www.xiayf.org/

正则表达式: https?//[/w.]+?/

结果:

Matches Found: 2

Match

Position

Length

http://www.shu.edu.cn/

11

22

https://www.xiayf.org/

38

22

4. 匹配的重复次数

上次几种正则表达式的缺陷:

+和*匹配的字符个数没有上限。我们无法为它们将匹配的字符个数设置一个最大值。

+,*和?至少匹配零个或者一个字符。我们无法为它们将匹配的字符个数另行设定一个最小值。

如果只使用+和*,我们无法把它们将匹配的字符个数设定为一个精确的数字。

解决方法:重复次数用{和}来给出---把数值写在它们中间。

( 1 )为重复匹配次数设定一个精确的值

例子:

文本

一段文本中有一个 ipv6 地址为:

daiodhqoidqw 1080:0000:0000:0000:0008:0800:200C:417Adajd9w0quednaldjojdi

正则表达式:(/w{4}:){7}(/w{4})

结果

Matches Found: 1

Match

Position

Length

1080:0000:0000:0000:0008:0800:200C:417A

12

39

(2 )为重复匹配次数设定一个区间

也就是为重复匹配次数设定一个最大值和最小值。

例子

文本:

4/8/03

10-6-2004

2/2/2

01-01-01

正则表达式: /d{1,2}[-//]/d{1,2}[-//]/d{2,4}

结果:

Matches Found: 3

Match

Position

Length

4/8/03

0

6

10-6-2004

7

9

01-01-01

23

8

如果想匹配“至少重复多少次”,也即最少要重复匹配多少次,则可把区间格式里的第二个数字省略。但 , 不可省略。

例子

文本和上例相同

正则表达式: /d{1,2}[-//]/d{2,}[-//]/d{2,4}

结果:

Matches Found: 1

Match

Position

Length

01-01-01

23

8

5. 防止过度匹配

?只能匹配零个或一个字符,{ n }和{ m,n }也有一个重复次数的上限;换句话说,这几种语法所定义的“重复次数”都是有限的,但是上述其他几种重复匹配语法在重复次数方面没有上限,而这样做有时会导致过度匹配的现象。

例子:

文本

this offer is not available to customers

living in <B>AK</B> and <B>HI</B>

说明:我们希望把两个 <B> </B> 之间的内容取出来,但是不要其中的 and

正则表达式: <[Bb]>.*</[Bb]>

结果:

Matches Found: 1

Match

Position

Length

AK and HI

51

23

显然结果不符合我们的预期。为什么会这样呢?因为*和+都是所谓的“贪婪型”元字符,它们在进行匹配时的行为模式是多多益善而不是适可而止。那怎么办呢?答案是使用这些元字符的“懒惰型”版本。

         常用的贪婪型元字符和它们的懒惰型元字符

贪婪型元字符         懒惰型元字符

*                          *?

+                          +?

n, }                  { n, }?

则上例的正则表达式可改为: <[Bb]>.* </[Bb]> 即可。

(未完待续)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值