您的位置:首页 > 其它

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

2010-02-19 22:29 211 查看

.

使用元字符

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

即可。

(未完待续)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: