PHP正则表达式的学习

自己的打算就是这几天好好学下正则表达式 把自己的学习过程都写在这上面 觉得我菜的 也希望不要喷我。。。只是跟大家一起分享下

常用的正则匹配的函数

preg_match ( $pattern, $subject, [ array &$matchs ] ); //执行匹配正则表达式
preg_match_all ( $pattern, $subject, array &$matches ); //执行一个全局正则表达式匹配
这两个什么意思呢 ? 一个例子 给大家看下 通俗的讲就是一个匹配一次就停止 一个就是匹配到结束
在这里插入图片描述
PS(上面的 第三行注释 ‘//执行一个全局正则表达式匹配’ 应该是 ‘//执行一个正则表达式匹配’)
preg_replace ( $pattern, $replacement, $subject ) ////执行一个正则表达式的搜索和替换

<?php

$t1 = "123456789";
$a = preg_replace('/[0-9]/', "6",$t1);//执行一个全局正则表达式匹配
echo $a;
---------------------------------------------------------------------------------
结果:
666666666

preg_grep ( $pattern, array $input ) // 返回匹配模式的数组条目 只做匹配,不做替换
一个例子大家就懂了

<?php
$array = array(1, 2, 3.4, 53, 7.9);
// 返回所有包含浮点数的元素
$fl_array = preg_grep("/^(\d+)?\.\d+$/", $array);
print_r($fl_array);
-----------------------------------------------------------
结果:
Array ( [2] => 3.4 [4] => 7.9 )

定界符

这里讲解下 两边的’ / ’ 是定界符 起到一个指示的作用 ,/之间的部分就是将要在目标对象中进行匹配的模式
这边的匹配的模式是这样的^(\d+)?.\d+$ 分析一下 ^ 可以理解为 以什么开头 这里就是以 ^数字开头 中间有点.
之后是以数字结尾$ 来匹配

元字符

/a/中的a就是一个元字符,一个元字符匹配一个实体字符,这里的“a”没有特殊含义,就匹配一个英文a
像/\d/就匹配0到9的所有数字,如果两个连写/\d\d/就可以匹配10到99的所有数字 /./可以匹配任何字符

所谓的”导字符“ 就是例如

\d+ 其中 ‘\d’ 就是导字符

基础的元字符 如下:

+ 匹配导字符 一次或者多次出现
* 匹配导字符 零次或者多次出现 ? 匹配导字符 零次或一次出现
\s:用于匹配单个空格符,包括tab键和换行符
\S:用于匹配除单个空格符之外的所有字符
\d:用于匹配从0到9的数字
\w:用于匹配字母,数字或下划线字符
\W:用于匹配所有与\w不匹配的字符
x\bx : 用于匹配定位符x开头或者结尾的字符串 .
:用于匹配除换行符之外的所有字符

/love/
其中位于“/”定界符之间的部分就是将要在目标对象中进行匹配的模式。用户只要把希望查找匹配对象的模式内容放入“/”定界符之间即可。为了能够使用户更加灵活的定制模式内容,正则表达式提供了专门的“元字符”。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
/fo+/
因为上述正则表达式中包含“+”元字符,表示可以与目标对象中的 “fool”, “fo”, 或者 “football”等在字母f后面连续出现一个或多个字母o的字符串相匹配。
/eg*/
因为上述正则表达式中包含“*”元字符,表示可以与目标对象中的 “easy”, “ego”, 或者 “egg”等在字母e后面连续出现零个或多个字母g的字符串相匹配。
/Wil?/
因为上述正则表达式中包含“?”元字符,表示可以与目标对象中的 “Win”, 或者 “Wilson”,等在字母i后面连续出现零个或一个字母l的字符串相匹配。
/jim{2,6}/
上述正则表达式规定字符m可以在匹配对象中连续出现2-6次,因此,上述正则表达式可以同jimmy或jimmmmmy等字符串相匹配。
/\bbom/
因为上述正则表达式模式以“\b”定位符开头,所以可以与目标对象中以 “bomb”, 或 “bom”开头的字符串相匹配。
/man\b/
因为上述正则表达式模式以“\b”定位符结尾,所以可以与目标对象中以 “human”, “woman”或 “man”结尾的字符串相匹配。

现在我们再讲深一点

集合

比如:

/[A-Z]/ 上述正则表达式将会与从A到Z范围内任何一个大写字母相匹配。

/[a-z]/ 上述正则表达式将会与从a到z范围内任何一个小写字母相匹配。

/[0-9]/ 上述正则表达式将会与从0到9范围内任何一个数字相匹配。 记住[] 这个只是匹配单个字符的用法

/([a-z][A-Z][0-9])+/ 上述的正则表达式讲会从第一位a-z第二位A-Z第三位0-9+ 或者是多个数字相匹配

分组

/.(c|le)ss/ 上述正则表达式将会匹配后缀名为 .css 或者 .less的字符串
/(asd)(_\1)+/ 上述正则表达式将会匹配 asd_asd_asd_asd 重复的字符串 其中的表达式 \1 的意思就是重复匹配第一个分组里面的字符串

量词

比如 /\d/ 这只能匹配单个数字的表达式 那么我们需要匹配一个相同但是连续的 要如何匹配呢 这里我们就需要用到两次

如 /\d{2,3}/ 上述正则表达式将会匹配到 一个数字二到三个 如 /3{1,6}/ 上述正则表达式将会匹配到 一个数字为3的
1到6个
那么我们可以想下 *+?这三种元字符 写成量词的话那其实就是以下三种了
+代表1到多,等于{1,}
*代表0到多,等于{0,}
?代表0或1个,等于{0,1}

这里我们最需要知道的一个点是 我们的正则表达式 是以表达式 去匹配字符串 而不是 拿我们的字符串去匹配表达式,这一点我们需要知道,成立的永远不是字符串 而是匹配的表达式 就是正则 ,emm,大家应该懂我意思吧,算了 我一个专科生 就这么点水平了。。

现在我们可以在来讲下(贪婪模式非贪婪模式

量词有个尴尬的地方,比如用/.a/去匹配 ‘123a123a’,本来希望得到’123a’,实际却得到’123a123a’。这是因为任何字符都满足/./加上量词会导致从头匹配到尾,但因为我们还有其他元字符,所以这时正则引擎会回溯,将已经匹配的结果从后往前一个个拿出来,与剩下的元字符相匹配。
这种模式叫贪婪模式,它可能会产生预期之外的结果和不必要的性能浪费
解决方案是使用非贪婪模式,在量词后面加?问号可以得到最小结果,现在使用/.
?a/去匹配就可以得到’123a’了。任何量词后都可以使用非贪婪模式

我们再讲深入一点的知识 (环视)

环视

x(?=y)这个功能有很多种翻译,比如零宽断言,我个人感觉比较准确的是“正向肯定环视”
x(?!y)正向否定环视
x代表元字符,y也代表元字符,x(?=y)的意思是紧接着y的x,比如 ‘-1a–2b-’,使用/\d(?=a)/去匹配,会得到1;/\d(?!a)/去匹配,会得到2。
这功能怎么用?举个例子,有一段字符串’a(123)b’,我只想要括号内的内容,但不想要括号
我需要匹配到右括号左边的位置,那么我可以写成/(?=))/(注意括号需要转义),我不想要左括号/[^(]/,我不关心括号内的内容/.*/,这时组合三个正则就变成了/[^(].*(?=))/
实际上这个功能匹配的是位置,从匹配到的位置开始找元字符,所以你如果在环视后面加量词是没用的

标识符

g:一个正则只会匹配一次,如果加上g标识符就会全局匹配, /\d/g,这个正则是不管两个数字之间隔了什么,都会将所有数字匹配出来
i:不区分大小写/^http:///i就会匹配http://和HTTP://

练习:

一.校验数字
数字:^[0-9]*$
n位的数字:^\d{n}$
至少n位的数字:^\d{n,}$
m-n位的数字:^\d{m,n}$
零和非零开头的数字:^(0|[1-9][0-9]*)$
非零开头的最多带两位小数的数字:^([1-9][0-9]*)+(.[0-9]{1,2})?$
带1-2位小数的正数或负数:^(\-)?\d+(\.\d{1,2})?$
正数、负数、和小数:^(\-|\+)?\d+(\.\d+)?$
有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
有1~3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
非零的正整数:^[1-9]\d*$
非零的负整数:^\-[1-9][]0-9"*$
非负整数:^\d+$
非正整数:^-[1-9]\d*|0$
非负浮点数:^\d+(\.\d+)?$
非正浮点数:^((-\d+(\.\d+)?)|(0+(\.0+)?))$
正浮点数:^[1-9]d.d|0.d[1-9]d$
负浮点数:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$
浮点数:^(-?\d+)(\.\d+)?$
二.效验字符
汉字:^[\u4e00-\u9fa5]{0,}$
英文和数字:^[A-Za-z0-9]+$
长度为3-20的所有字符:^.{3,20}$
由26个英文字母组成的字符串:^[A-Za-z]+$
由26个大写英文字母组成的字符串:^[A-Z]+$
由26个小写英文字母组成的字符串:^[a-z]+$
由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
由数字、26个英文字母或者下划线组成的字符串:^\w+$
中文、英文、数字包括下划线:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、数字但不包括下划线等符号:^[\u4E00-\u9FA5A-Za-z0-9]+$
可以输入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止输入含有~的字符:[^~\x22]+
三.特殊需求表达式
Email地址:^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
手机号码:^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$(国内 13、15、18开头的手机号正则表达式,可根据目前国内收集号扩展前两位开头号码)
电话号码("XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX):^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$
国内电话号码(0511-4405222、021-87888822):\d{3}-\d{8}|\d{4}-\d{7}
身份证号(15位):^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$
身份证号码(18位):^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$
帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
密码(以字母开头,长度在6~18之间,只能包含字母、数字和下划线):^[a-zA-Z]\w{5,17}$
强密码(必须包含大小写字母和数字的组合,不能使用特殊字符,长度在8-16之间):^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,16}$
日期格式:^\d{4}-\d{1,2}-\d{1,2}
一年的12个月(01~09和1~12):^(0?[1-9]|1[0-2])$
一个月的31天(01~09和1~31):^((0?[1-9])|((1|2)[0-9])|30|31)$
xml文件:^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$
中文字符的正则表达式:[\u4e00-\u9fa5]
双字节字符:[^\x00-\xff] (包括汉字在内,可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1))
空白行的正则表达式:\n\s*\r (可以用来删除空白行)
首尾空白字符的正则表达式:^\s*|\s*$或(^\s*)|(\s*$) (可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式)
腾讯QQ号:[1-9][0-9]{4,11} (腾讯QQ号从10000开始)
中国邮政编码:[1-9]\d{5}(?!\d) (中国邮政编码为6位数字)
IP-v4地址:\\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b (提取IP地址时有用)
校验IP-v6地址:(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))
子网掩码:((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
校验日期:^(?:(?!0000)[0-9]{4}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8])|(?:0[13-9]|1[0-2])-(?:29|30)|(?:0[13578]|1[02])-31)|(?:[0-9]{2}(?:0[48]|[2468][048]|[13579][26])|(?:0[48]|[2468][048]|[13579][26])00)-02-29)$(“yyyy-mm-dd“ 格式的日期校验,已考虑平闰年。)
抽取注释:<!--(.*?)-->
查找CSS属性:^\\s*[a-zA-Z\\-]+\\s*[:]{1}\\s[a-zA-Z0-9\\s.#]+[;]{1}
提取页面超链接:(<a\\s*(?!.*\\brel=)[^>]*)(href="https?:\\/\\/)((?!(?:(?:www\\.)?'.implode('|(?:www\\.)?', $follow_list).'))[^" rel="external nofollow" ]+)"((?!.*\\brel=)[^>]*)(?:[^>]*)>
提取网页图片:\\< *[img][^\\\\>]*[src] *= *[\\"\\']{0,1}([^\\"\\'\\ >]*)
提取网页颜色代码:^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
文件扩展名效验:^([a-zA-Z]\\:|\\\\)\\\\([^\\\\]+\\\\)*[^\\/:*?"<>|]+\\.txt(l)?$
判断IE版本:^.*MSIE [5-8](?:\\.[0-9]+)?(?!.*Trident\\/[5-9]\\.0).*$

猜你喜欢

转载自blog.csdn.net/q1352483315/article/details/89462646
今日推荐