您的位置:首页 > 其它

正则表达式

2015-02-04 10:33 309 查看

定锚点,去噪点,取数据

1、入门:正则字符

关于正则字符,很多文章都会讲到,足足有一篇文章才能描述清楚,我这里就不多说,对于我,平时,常用的有:

.
匹配不包括换行的任意字符,在php的s修饰符下面可以匹配换行,如
$pattern='#<div>(.*?)</div>#s';
就可以匹配div内容有换行的数据。

\s
空格、tab

*
匹配零个或多个

+
匹配一个或多个,即至少一个

\
转义

一个特殊字符前加
\
就表示转义,说明把它当普通字符用

[]
单字符取一个,比如[abc]会匹配
a或b或c


但是,如果
[]
里面加上
^
则会变成排除这个字符,如
[^abc]
就表示
不是a、不是b、也不是c
另外,在
[]
里面可以使用
-
表示一个范围,如
[0-9]
表示从0到9,类似的还有
[a-zA-Z]
,如果要包含
-
字符,可以给它加上转义
[\-]


^
一行字符串开始(虚拟字符,不实际存在)

这里的^跟
[]
里面用的
^
是同一个字符,但是却不是一个意思,这里它表示一行字符串的开始,比如
^www
表示以
www
开头的字符串,注意区分,不在
[]
里面的是开始符,在里面的排除

$
一行字符串结束(虚拟字符,不实际存在)

{1,3}
循环次数

[0-9]{1,3}
表示在0-9的范围里面循环1个、2个或者3个,可能结果有5、20、415等

?
有两个用法

(1) 匹配一个或零个,比如
https?
匹配的
https
(一个s)或者http(零个s)

(2)非贪婪模式

所谓非贪婪模式,就是匹配尽可能少的内容,比如,对于源字符串

<div>


a


</div>


<div>


b


</div>


使用
<div>(.*?)</div>
会得到2个结果:

<div>


a


</div>




<div>


b


</div>


因为,当遇到第一个
</div>
,非贪婪模式就不会再往后找了。 而使用
<div>(.*)</div>
(贪婪模式)则会得到整个字符串

<div>


a


</div>


<div>


b


</div>


,因为它会匹配所有字符直到后面再找不到
</div>
。 11.
|
多个数据选一(常用于多字符) 前面提到
[]
里面的字符有选一个字符功能,但是假如不是一个字符,比如:http|ftp|svn 就需要用
|
分开,
|
的作用域是一直往后直到遇到括号,比如,对于源字符串

http abc


ftp abc


svn abc


http|ftp|svn abc
匹配的结果是:

http




ftp




svn abc


想要匹配
http abc
ftp abc
svn abc
就要使用括号把前边的协议括起来,如
(http|ftp|svn) abc
可以得到预期的结果。 12.
()
数据分界和取数据

上面例子
(http|ftp|svn) abc
就是数据分界的例子,然后,匹配结果会得到一个[1]的子集数据,这里就是子模式的概念,利用子模式,可以得到想要取出来的数据。子模式1、2、3的计算方法为左括号的计数,从左到右,从1开始,比如:
(http|ftp|svn)://([^/]+)
,[1]得到的是
(http|ftp|svn)
里面的数据,[2]得到
([^/]+)
里面的数据,对于嵌套括号也是点左括号即可。 13.
(?:)
非捕获组 上面说到
()
作为子模式可以得到它里面的数据,但是,有些时候,
()
只是作为数据分界功能,并不需要取出来,这时候就要用到非捕获组的概念了。比如:
(http|ftp|svn)://([^/]+)
只想得到域名,也就是[2],那么
(http|ftp|svn)
就只是数据分界的功能,这里不需要捕获,因此使用非捕获组功能,
(?:http|ftp|svn)
屏蔽这部分的数据获取,此时,
(?:
这个左括号要排除出[1]、[2]计数,也就是
(?:http|ftp|svn)://([^/]+)
中的
([^/]+)
变成[1]了。

关于常用字符的使用差不多到这里,还有更多的请参考正则表达式30分钟入门教程,这是我看过比较全面的正则入门资料。

2、 操作:定锚点

每一个正则都是有针对性的,只有这样正则才有意义。因此,写正则之前,先观察你要解析的数据,找准唯一的锚点,比如,你要解析一个页面的title标签,得到title内容,那么这个title就是锚点。有时候,所要取的数据确实无法定位一个唯一的锚点,那么,你可以分解数据,先通过一个唯一锚点锁定你的数据块,取出来之后,再对这个数据块取数据即可。比如,有这么一段源字符串:

<div id="module_1">


<div class="content">


content 1


</div>


</div>


<div id="module_2">


<div class="content">


content 2


</div>


</div>


你直接通过class="content"来匹配数据的话很明显会得到两个,那么,你可以扩展它的数据域,先以id="module_1"作为锚点,获取整个

<div id="module_1">


<div class="content">


content 1


</div>


</div>


然后在对这个数据块的数据处理,得到class="contents"的内容即可。 因此,这里用到2个正则:

(1)
<div id="module_1">(.*?)</div>\s*<div id="module_2">
(2)
<div class="content">(.*?)</div>


总结:锚点,就是能唯一定位你数据的标识

3、 操作:去噪点

所谓去噪点,就是把无关的东西都当浮云,用通配符过掉它,只关心我们想要的数据,比如:
<meta content="text/html; charset=utf-8" http-equiv="content-type">
要从这里得到字符集utf-8,我们需要怎么做? 首先,定位锚点,有
<meta
charset=
和utf-8后面的
"
,其他都是浮云~ 因此得到正则:
<meta[^>]*?charset=([^"]+)"
即可,用子模式取数据[1]就能得到utf-8

总结:关心的留下,不关心的都是浮云

4、 操作:取数据

关于取数据,上面一大篇下来大家应该有概念了,就是利用子模式来获取,这里不再赘述。

总结:子模式计数,数左括号从1开始,排除非捕获组的左括号

转载原文地址:我眼里的正则表达式(入门)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: