PHP 由0开始学习 正则表达式

1.学习前的例子  

       0\d\d-\d\d\d\d\d\d\d\d匹配这样的字符串:以0开头,然后是两个数字,然后是一个连字号“-”,最后是8个数字(也就是中国的电话号码。当然,这个例子只能匹配区号为3位的情形)。比如说电话号码是086-54878451
      当然了,这个表达式看上去 确实有点烦人我们可以这样写:
       0\d{2}-\d{8}。这里\d后面的{2}({8})的意思是前面\d必须连续重复匹配2次(8次)
       好了,我们开了好头,然后请看下面的文章

2.工具

至于辅助的工具 网上是有那么一种工具,或者现在工具网站也有很多,帮助你测试组装你的正则表达式

正则表达式测试器(v1.1.0)  

3.首先来认识下 正则中的几种字符

表1.常用的元字符
代码说明
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线或汉字
\s匹配任意的空白符
\d匹配数字
\b匹配单词的开始或结束
^匹配字符串的开始
$匹配字符串的结束
       元字符^(和数字6在同一个键位上的符号)和$都匹配一个位置,这和 \b 有点类似。^匹配你要用来查找的字符串的开头,$匹配结尾。这两个代码在验证输入的内容时非常有用,比如一个网站如果要求你填写的QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$
       这里的{5,12}和前面介绍过的{2}是类似的,只不过{2}匹配只能不多不少重复2次,{5,12}则是重复的次数不能少于5次,不能多于12次,否则都不匹配。
       因为使用了^和$,所以输入的整个字符串都要用来和\d{5,12}来匹配,也就是说整个输入必须是5到12个数字,因此如果输入的QQ号能匹配这个正则表达式的话,那就符合要求了。
       和忽略大小写的选项类似,有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项,^和$的意义就变成了匹配行的开始处和结束处。

表2.常用的限定符
代码/语法说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次
表3.常用的反义代码
代码/语法说明
\W匹配任意不是字母,数字,下划线,汉字的字符
\S匹配任意不是空白符的字符
\D匹配任意非数字的字符
\B匹配不是单词开头或结束的位置
[^x]匹配除了x以外的任意字符
[^aeiou]匹配除了aeiou这几个字母以外的任意字符

表4.模式修饰符

模式修饰符的作用是设定模式,也就是正则表达式如何解释。php中主要模式如下表:

修饰符说明
i忽略大小写
m多文本模式
s单行文本模式
x忽略空白字符
 

4.转义

反斜杠 \  , 转义字符主要是将一些特殊字符转为普通字符。而这些常用特殊字符有”.”,”?”、”\”等。
 

5 下面来一点例子。

1. 简单匹配数字

$patterns = "/\d+/"; //第一种
$strs="left:0px;top:202px;width:90px;height:30px";
preg_match_all($patterns,$strs,$match);
echo '<pre>';
print_r($match);

上述会输出
Array
(
    [0] => Array
        (
            [0] => 0
            [1] => 202
            [2] => 90
            [3] => 30
        )

)

2.加了限定符

^once   该模式与字符串"once upon"匹配,与"There once ..."不匹配
^a{2,4}$ aa,aaa或aaaa
^a{1,3}$ a,aa或aaa
^a{2,}$ 包含多于两个a的字符串
^a{2,} 如:aardvark和aaab,但apple不行
 a{2,} 如:baad和aaa,但Nantucket不行

3.好我们来匹配一个手机号(一般都是11位吧)
$patterns = "/\d{11}/"; //第一种 也可以这样 /1[3458]\d{9}/  方括号表示第二个数字只能是3或4或5或8
$strs="你好,我的手机号是15916882974";
preg_match($patterns,$strs,$match);//和preg_match_all不同,这个是匹配到的第一个
echo '<pre>';
print_r($match);

上述会输出:
Array
(
    [0] => 15916882974
)

4.判断字符串”I am a good boy”中是否包含单词go

$pattern=’/\bgo\b/’;

\b是匹配单词的开始或结束
首先判断是单词,而不是字符串,因此比较的时候,需要比较是否包含’ go ‘,即在字符串go前后有一个空格。
解析:如果使用非正则比较,只需要调用上面的strpos()函数即可,注意,第二个参数前后要加一个空格,即’ go ‘。
很显然这里是匹配不上的

5.正则匹配图片

/<(img|IMG).+?\/>/i

匹配一张图片,其中 .+? 属于非贪婪匹配,下面会说到
上面的img|IMG用到了分支这种写法,一般用[ ] 括起来

6.匹配字符串 'php'

if (preg_match("/php/i", "PHP is the web scripting language of choice.")) {
    echo "查找到匹配的字符串 php。";
} else {
    echo "未发现匹配的字符串 php。";
}


正则中说的 贪婪与懒惰

当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下)匹配尽可能多的字符。以这个表达式为例:a.*b,它将会匹配最长的以a开始,以b结束的字符串。如果用它来搜索aabab的话,它会匹配整个字符串aabab。这被称为贪婪匹配。

有时,我们更需要懒惰匹配,也就是匹配尽可能少的字符。前面给出的限定符都可以被转化为懒惰匹配模式,只要在它后面加上一个问号?。

这样.*?就意味着匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复。

现在看看懒惰版的例子吧:

a.*?b匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)。

再比如:

我们再来看一个例子
$str = '<td>bread1</td><td>bread2</td>';
preg_match('/<td>(.*)<\/td>/',$str,$res);
print_r($res);
输出:
Array
(
    [0] => bread1bread2 
    [1] => bread1bread2 
)
可以看到 这里把2个单元格的值都匹配出来了(由于存在子表达式所以一共匹配了2次)
$str = '<td>bread1</td><td>bread2</td>';
preg_match('/<td>(.*?)<\/td>/',$str,$res);
print_r($res);

输出:
Array
(
    [0] => bread1 
    [1] => bread1 
)

进阶篇

1.匹配图片的src

$patterns = "/<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/i";
$strs="<img   src='img1.jpg' alt='rererere'/><IMG src='img2.jpg' title='223'/>";
preg_match($patterns,$strs,$match);
echo '<pre>';
print_r($match);

输出:

Array
(
    [0] => <img src="img1.jpg" alt="rererere">
    [1] => img1.jpg
)

可以看到这里的匹配结果img1.jpg ,也是使用了懒惰的匹配模式。img和src之间如果用.* 有可能一直匹配到图片的尾部。这里用了懒惰匹配就保证匹配的是

img和src之间的最短距离.

2.匹配邮件格式

$patterns = "/\d{1,}@.*?\.(com|cn)/i";
$strs="hello,my email is 100023@qq.com。And liming's email is 66666@sina.cn 。welcome join us!";
preg_match_all($patterns,$strs,$match);
输出:
Array
(
    [0] => Array
        (
            [0] => 100023@qq.com
            [1] => 66666@sina.cn
        )
    [1] => Array
        (
            [0] => com
            [1] => cn
        )
)
有一点值得注意的是:

选择字符表示或的意思。如Aa|aA,表示Aa或者是aA的意思。注意使用”[]”与”()”的区别,在于”[]”只能匹配单个字符,而”()”可以匹配任意长度的字符串。在使用”[]”的时候,往往配合连接字符”-“一起使用,如[a-d],代表a或b或c或d。

所以这里的表达式中的(com|cn)  如果改成 [com|cn] ,就会 输出

Array

(

    [0] => Array

        (

            [0] => 100023@qq.c

            [1] => 66666@sina.c

        )

)

所以就是说[ ]只能匹配单个字符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿John

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值