PHP正则表达式
工作一段时间,慢慢回首发现很多最初的问题都忘记了,只能记住问题的解决方法,然后去度娘那找一下。抽出时间,慢慢温习下之前走过的路
正则表达式
1、正则表达式介绍
处理字符串时,有很多较为复杂的字符串用普通的字符串处理函数无法干净的完成。比如说,可能需要验证一个Email 地址是否合法,为此需要查看许多不容易检查的规则。这正是正则表达式的用武之地。正则表达式是功能强大而简明的字符组,其中可以包含大量的逻辑,特别值得一提的是正则表达式相当简短。
php最开始使用的是POSIX Regex风格函数,函数以ereg开头,如ereg_replace(),这套函数从php5.3.0起正式被废除。现在我们使用的是PCRE正则表达式,这套正则表达式基本上就是大名鼎鼎的Perl风格的正则表达式,但又有所不同。
Perl 一直被认为是最伟大的解析语言之一,它提供了一种全面的正则表达式,即使是最复杂的字符串模式,也可以用这种正则表达式语言搜索和替换。PHP 开发人员认识到,与其重新发明正则表达式,不如让PHP 用户直接使用声名赫赫的Perl 正则表达式语言,即Perl风格的函数。
各个编程语言都有正则表达式,且支持的语法大致相同,但又有细微的差别。如php和JavaScript中的正则表达式基本相同,只有微小的差别。
学习网址:
http://www.zjmainstay.cn/my-regexp
百度百科
书籍:《精通正则表达式》
2、正则表达式语法
案例:从一个字符串中php,查找是否有p字母。
一个函数:preg_match(正则表达式, 需要进行查找的字符串);
正则语法: '/正则表达式/'
用正则的办法查找字符串中是否有p: preg_match('/p/', 'php'); 查找的结果是1次或者是0次,如果没有查找到,那么返回0次;如果查找到了一次p,就会停止向后搜索,并返回1次。
3、量词
前导字符:紧挨着量词(如+、?...)的前一个字符。
语法 语法描述 示例
+ 匹配任何至少包含一个前导字符 preg_match('/ph+p/', 'adfsphhhpasdf')
* 匹配任何包含零个或多个前导字符串 preg_match('/ph*p/', 'adfsppasdf');
? 匹配任何包含零个或一个前导字符串 preg_match('/ph?p/', adfsppasdf')
. 匹配任意字符,只能表示一个字符
.* 匹配任意字符串。
{x} 匹配任何包含x 个前导字符串 preg_match('/ph{3,}p/', 'phhhhp')
{x,y} 匹配任何包含x 到y 个前导字符串
{x,} 匹配任何包含至少x 个前导字符串
$ 匹配字符串的行尾 preg_match('/php$/', '123 php')
^ 匹配字符串的行首 preg_match('/^php/', 'php123')
^string$ 只匹配字符串string preg_match('/^php$/', 'php')
| 匹配字符串的左边或者右边 preg_match('/asp|php|jsp/', '234asp235')
() 包围一个字符分组或定义个反引用,可以使用\1\2提取反引用,可以用$1/$2提取字符分组 ()表示捕获
\1 表示引用捕获
4、元字符
语法 语法描述
[a-z] 匹配任何包含小写字母a-z的字符串,[a-z]表示一个小写字母
[A-Z] 匹配任何包含大写字母A-Z的字符串
[0-9] 匹配任何包含数字0-9的字符串
[b-f] 匹配任何包含小写字母b-f的字符串
[abc] 匹配任何包含小写字母a、b、c 的字符串,只要有a/b/c中的任意一个就匹配
[^abc] 匹配任何不包含小写字母a、b、c 的字符串,只要字符串中不全是abc就匹配
[a-zA-Z0-9_] 匹配任何包含a-zA-Z0-9 和下划线的字符串
[]说明 []里面可以是一个范围,也可以是单个字符
\w 匹配任何包含a-zA-Z0-9 和下划线的字符串(同上上)
\W 匹配任何没有下划线和字母数字的字符串,和\w相反
\d 匹配任何数字字符,和[0-9]相同
\D 匹配任何非数字字符,和[^0-9]相同
\s 匹配任何空白字符和\r\n等制表符preg_match('/\s/', "\r\n")
\S 匹配任何非空白字符非制表符
\b 匹配是否到达了单词边界 w\b w是不是单词的开头 \bw w是不是单词的结尾
\B 匹配是否没有达到单词边界
\ 匹配正则中的特殊字符,转义字符
5、修饰符
格式:
'/正则表达式/修饰符'
语法 语法描述
i 完成不区分大小写的搜索preg_match('/A/i', "asdfasdf")
m 在匹配首内容或者尾内容时候采用多行识别匹配preg_match('/^nice/im', "hello world\nNice to meet you")
x 忽略正则中的空白
A 强制从头开始匹配
U 禁止贪婪匹配只跟踪到最近的一个匹配符并结束
u 表示匹配utf-8编码的字符
6、PCRE正则表达式常用函数
1、preg_match()
2、preg_match_all()
这个函数和preg_match的区别是,preg_match_all在匹配一次结果后,并不会终止搜索,还会继续向后搜索,一直到字符串的结尾。
3、preg_replace()
正则替换,将匹配到的结果替换成另一个字符串
7、捕获和反引用
正则中,小括号里面的内容,叫做捕获的内容。用“\数字”引用捕获的内容。
1、(exp)匹配exp,并捕获文本到自动命名的组里
2、(?<name>exp) 匹配exp,并捕获文本到名称为name的组里,也可以写成(?'name'exp),用\k<name>引用
3、(?:exp)匹配exp,不捕获匹配的文本,也不给此分组分配组号
8、匹配中文
1、web开发中的编码介绍
实际上有两种编码。
第一种编码是比较常见的,就是在代码中体现的:
如HTML5中:<meta charset='utf-8' />
如HTML4.01:<meta http-equiv="content-type" content="text/html;charset=utf-8" />
如PHP中:header('content-type:text/html;charset=utf-8');
这种编码表示浏览器要用utf-8的编码解释我们的网页。
第二种编码是文件编码:
文件用记事本打开,另存为,选择的编码。UTF-8表示UTF-8编码;ANSI表示gbk或gb2312编码。
所以,想要页面不乱码,文件编码和让浏览器解释的编码要保持一致。
2、UTF-8编码字符 /[\x{4e00}-\x{9fa5}]/u
/[\x{4e00}-\x{9fa5}]/u:这种写法可以匹配一个中文。
2、GBK/GB2312编码:[x80-xff]+
这个正则不能匹配单个汉字,只能匹配连续的汉字。
3、案例—解决结巴问题
我我我要要要上...厕厕所 我要上厕所
方法一:
方法二:
去掉…的办法:
9、环视(断言/零宽断言)
1、(?<=exp) 匹配前面是exp的数据
(?<=B)AAA 匹配前面是B的数据,即BAAA匹配,而CAAA不匹配
2、(?<!exp) 匹配前面不是exp的数据
(?<!B)AAA 匹配前面不是B的数据,即CAAA匹配,而BAAA不匹配
3、(?=exp) 匹配后面是exp的数据
AAA(?=B) 匹配后面是B的数据,即AAAB匹配,而AAAC不匹配
4、(?!exp) 匹配后面不是exp的数据
AAA(?!B) 匹配后面不是B的数据,即AAAC能匹配,而AAAB不能匹配
另外,还会看到(?!B)[A-Z]这种写法,其实它是[A-Z]范围里,排除B的意思,前置的(?!B)只是对后面数据的一个限定,从而达到过滤匹配的效果。
环视排除案例:
注册的时候,用户名要求不能全部是数字,也不能全部是字母,必须是数字字母组合。长度是3~5位。
10、案例
1、手机号验证
特点:
纯数字
11位
开头为1
2/3位固定,如果要验证这个,必须和运营商联系。
2、邮箱验证
特点:
[email protected]
[email protected]
@前面要求:
域名要求:sina/sohu/163
.后面:可以是com,可以是cn
3、禁止贪婪匹配
加入U修饰后的结果: