正则表达式入门教程

正则表达式入门教程

一、入门:正则字符

1..匹配不包括换行的任意字符

如果需要匹配包括换行的任意字符,可以使用[\s\S]代替.

2.\s匹配空格、tab、换行

[\s\S]表示匹配任意字符,\S\s的反义
注意区分[\s\S]与.的区别

3.*匹配零个或更多个,即0~N

4.+匹配一个或更多个,即至少一个,1~N

5.,\转义

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

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

但是,如果[ ]里面加上^则会变成排除这个字符,如[^abc]就表示不是a,不是b,也不是c

另外,在[ ]里面可以是用-表示一个范围,如[0-9]表示0到9,类似的还有[a-zA-Z],如果要包含-字符,可以给它加上转义[\-]

关于[ ]常见的错误用法是: [ab|bc]用来表示abbc,实际上,它得到的结果是[abc|],即a或b或c或|这4个字符(单字符)的任意一个.这里可以改成(ab|bc)

总结:[]里面的特殊符有五个: []-\^,其他字符都是普通字符,包括*.?

说明:

^[^]的首位时才有特殊意义

[0-9]-不是首位才有特殊意义

\[ \]因为占用[ ]本身字符,所以有特殊意义

\本身是转义符,有特殊意义

7.^字符串开始

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

8.$字符串结束

9.{1,3}循环次数

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

如果循环指定次数,如3次,则可以写成{3}

如果刚好需要匹配字符{1},则正则需要给{j进行转义,等到\{1}的正则

如果{}中间不是数字,则{}本身不需要转义

10.?有两个用法

(1)、匹配一个或零个

比如https?匹配的http或者https

(2)、非贪婪模式

所谓非贪婪模式,就是匹配尽可能少的内容,比如:

<div>a</div><div>b</div>

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

<div>a</div>和<div>b</div>

因为,当遇到第一个</div>,非贪婪模式就不会再往后找了

而使用<div>(.*)</div>贪婪模式时,则会得到整个字符串

<div>a</div><div>b</div>

11.|多个数据选一

前面提到[]里面的字符有选一个字符功能,但是假如不是一个字符,比如: http|ftp|svn 就需要用|分开,|的作用域是一直往后直到遇到括号,比如:

http abc
ftp abc
svn abc

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

http
ftp
svn abc

想要匹配http abcftp abcsvn abc就要使用括号把前面的协议括起来,如(http|ftp|svn) abc

12.()数据分界和取数据

上面例子(http|ftp|svn) abc就是数据分界的例子,然后,匹配的结果会得到一个[1]的子集数据(数组下标1),

这里就是子模式的概念,子模式也叫分组,利用子模式可以得到想要取出来的数据,子模式1,2,3的计算方法为左括号的计数,从左到右,从1开始比如:

(http|ftp|svn)://([^/]+),分组1得到的是http或ftp或svn协议的名称,分组2得到是地址的数据,对于嵌套括号也是点左括号即可.在正则中有很多与括号结合的写法,在数左括号的时候,一定要注意,非捕获组合环视的左括号都是不需要数的.

在使用子模式的过程中,常见的两种写法是:\1$1

(1) \1是在正则表达式本身中引用分组1的内容,如:

我们要匹配111这样的连续出现3次的数字,我们可以写正则(\d)\1\1,(\d)匹配到第一个1,后面在引用这个匹配的内容,会得到111

(2) $1是在替换中调用分组的内容,如:

我们要替换链接参数name=Zjmainstayusername=Zjmainstay,我们可以使用正则name=([^$]+)替换为username=$1来实现,这里的$1就引用了分组1的结果Zjmainstay,因此得到我们想要的结果.

13.(?:)非捕获组

上面说到()做为子模式可以得到它里面的数据,但是,有些时候,()只是作为数据分界功能,并不需要取出来

这时候就要用到非捕获组的概念了,比如:(http|ftp|svn)://([^/]+)只想得到域名,也就是[2],那么(http|ftp|svn)就只是数据分界的功能,这里不需要捕获,因此使用非捕获组功能,(?:htpp|ftp|svn)屏蔽着部分的数据获取,此时,(?:这个左括号排除[1]计数,就是(?:http|ftp|svn)://([^/]+)的第二个括号变成[1]

14.分隔符

在一些语言中,你会发现正则第一个和最后一个字符是相同的,如:

/d+/

这个/ /在PHP中称为分隔符,正则表达式需要由分隔符闭合包裹.在PHP中,分隔符可以使任意非字母数字、非反斜线,非空白字符.这个概念很关键,它能帮助我们简化一些正则的书写,避免错误,如:

<div>.*?</div>

这个正则是错误的

原因是</div>/与分隔符相同,但是却没有做转义

对于这种情况,有两种解决方案:

(1) /<div>.*?<\/div>/

(2)#<div>.*?</div>#

方案(1)是对正则内部的分隔符做转义,方案(2)是规避了本来的/分隔符,使用#作为分隔符,从而避免/需要转义。
虽然很多情况下,都是看到前后一致的分隔符,但是,大家需要了解一下,[<div>.*?</div>]这个表达式在PHP里也是合法的。(不提倡使用,仅了解!)

15.模式修饰符

模式修饰符在许多程序语言中都支持的,比如最常见的是i,不区分大小写,如javascript里的/[a-z0-9]/i,表示匹配字母数字,不区分大小写。

二、操作:定锚点

注: 这里的锚点区分于正则原本关于锚点的定义,此处是确定的参照文本的意思,如a便签<a

每一个正则都是有针对性的,只有这样正则才有意义.因此,写正则之前,先观察你要解析的数据,找准唯一的锚点.

比如,你要解析一个页面的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>

当然,这个正则可以改进为:
<div id="module_1">\s*<div class="content">(.*?)</div>

注:为了更清晰查看,前面源码做了换行,匹配失败的朋友,可以修改 .*? 为 [\s\S]*? 修正正则。

三、 操作:去噪点

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

原文地址:http://www.zjmainstay.cn/my-regexp

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值