系统学习下正则表达式。
正则表达式
正则表单php中有2套正则函数 .1: PCRE库 2 : POSIX库 提供的函数(POSIX库被弃用)
在php中 一个正则分成三个部分 分隔符、表达式、修饰符
分隔符 / # % ! ~ 一般用/
修饰符:用于开启或关闭某种功能或模式
学习测试工具:火狐扩展 Regular Expression Tester 进行测试
一、元字符
1 . // 匹配除了换行符以外的任意字符
2 \w // 匹配字母或数字或下划线或汉字
3 \s // 匹配任意空白符
4 \d // 匹配数字
5 \b // 匹配单词的开始或者结束
6 ^ // 匹配字符串的开始
7 $ // 匹配字符串的结束
8 - // 表示范围 1-9
9 [] // 匹配括号中的任意一个字符
10 * + ? //量词
11
12 下面看一些列子
13 (1).匹配以字母a开始的单词
14 \ba\w*\b
15 (2) 匹配1个或更多的数字
16 \d+
17 (3) 匹配6个字符的单词
18 \b\w{6}\b //匹配 action 123456 ste_ph等
19 注意 正则表达式里"单词"指不少于1个的连续字母和数字
20
二、量词
1* //重复0或者更多次
2+ //重复1次或者更多次
3? //重复0次或者1次
4{n} //重复n次
5{n,} //重复n次或者更多次
6{n,m} //重复n到m次
三、字符组
1字符组里面的元字符不用转义 就是代表该符号
2[aeiou] //匹配任何一个英文元音字母
3[.?!] //匹配标点符号(. ? !)其中一个标点符号
4c[aou]t //匹配 cat cot cut 这3个单词 而caout 则不匹配
四、转义
1 一般用 反斜杠 \ 转义 ,还有一种是 用 \Q和\E扩起来里面的内容就是本身
2 baidu\.com 匹配 baidu.com
3 c:\\windows 匹配 c:\windows
4 \d+\Q.$.\E$ //匹配一个或者多个数字,紧接着是一个点号,然后是一个$ ,再然后是一个点号 ,\Q和\E之间的元字符都会作为普通字符用来匹配
五、反义
1 \W 匹配任意不是字母、数字、下划线、汉字的字符
2 \S 匹配任意不是空白符的字符
3 \D 匹配任意非数字的字符
4 \B 匹配不是单词开头或结束的位置
5 [^x] //匹配除了x 以外的任意字符
6 [^aeiou] //匹配除了aeiou这几个字母以外的任意字符
7
8 列子
9 1.不包含空白符的字符串
10 \S+
11 2.用尖括号扩起来、已a开头的字符串
12 <a[^>]+>
13 匹配 <a href="http://www.baidu.com" >
六、分支
1 要匹配
2 cat,hat,fat,toat
3 (c|h|f|to)at // | 表示分支, ()表示一个整体 也叫分组 后面提到
4 [ch]at = (c|h)at
5 思考以下案例
6 0\d{2}-\d{8} | 0\d{3}-\d{7}
7 这个表单式 能匹配2种连字号的电话号码 一种是3位区号8位本地号(如010-12345678)
8 一种是4位区号7位本地号(如0376-2233445)
七、分组
1常用分组语法
2捕获
3 (exp) 匹配exp,并捕获文本到自动命名的组里
4 (?<name>exp) 匹配exp,并捕获文本到名称为name的组里, 也可以写成 (?'name'exp)
5 (?:exp) 匹配exp 不捕获匹配的文本,也不给此分组分配组号
6
7零宽断言
8
9 (?=exp) //匹配exp前面的位置
10 (?<=exp) //匹配exp后面的位置
11 (?!exp) //匹配后面跟的不是exp的位置
12 (?<!exp) //匹配前面不是exp的位置
13
14注释
15 (?#comment) //提供注释辅助阅读,不对正则表达式的处理产生任何影响
16
17
18 简单的ip地址匹配
19 (\d{1,3}\.){3}\d{1,3}
20 上面会匹配 256.300.800.900 显然不对
21
22 ((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
23 默认情况下,每个分组都有拥有一个组号,规则,从左向右,以分组的左括号为标志,第一个出现的分组组号为1,第二为2,分组0 对应整个正则表达式
24
25 也可以指定子表单式的组名,语法如下:
26 ?<Word>\w+
27或
28 ?'Word'\w+
29这样就把\w+组名指定为Word
八、反向引用
1\b(\w+)\b\s+\1\b
2以上表达式可以匹配重复的单词 如go go 或者 kitty kitty
3要反向引用分组捕获的内容 可以使用 "\k<Word>" 所以上面也可以写成这样
4\b(?<Word>\w+)\b\s+\k<Word>\b
环视
1环视
21.顺序肯定环视(?=exp)
3
4 \b\w+(?=ing\b)
5 以上表达式查找一下句子时,会匹配 sing 和danc
6 i am singing while you are dancing
7
8
92.逆序肯定环视(?<=exp)
10 (?<=\bre)\w+\b
11 reading a book // 匹配 ading
12
13
14\b\w*q[^u]\w*\b //以上表达式匹配的是含字母q但后面不是u的单词
15但是出现Iraq ,Benq q在最后面的时候,他就会出错 因为[^u] //必须匹配一个
16
17可以这么解决
18 \b\w*q(?!u)\w*\b
193.
20顺序否定环视
21c(?![au]t\b)\w+t //匹配 chart等 不匹配 cat cut
22
234.
24逆序否定环视
25 (?<![a-z])\d{7} //前面不是小写字母的7位数字
贪婪/懒惰匹配
1贪婪/懒惰匹配
2默认贪婪匹配 尽可能的匹配多的
3a.*b // aabab 就是贪婪匹配
4a.*?b //匹配a开始以b结束的 短字符串
5
6懒惰限定符合
7 *? //重复任意次,但尽可能少重复
8 +? //重复1次或等多次, 但尽可能少重复
9 ?? //重复0次或1次 ,但尽可能少重复
10 {n,m}? //重复n到m次 ,但尽可能少重复
11 {n,}? //重复n次以上,但尽可能少重复
正则的常用模式
i 忽略大小写模式
m 多行模式
s 点号通配模式
U 懒惰模式
D 结尾限制
1"abc\n"
2
3%abc$% 匹配的
4
5%abc$%D 不匹配
正则表达式的效率与优化
1正则表达式的效率与优化
2 (a|b|c|d|e|f|g)
3 [abcdefg]
4 [a-g]
5 //第一种最慢不要用. 二三差不多
6
7 标准量词是匹配优先级的
8 copy2003y
9 \w*(\d+) \d匹配3 //\w*为匹配全部,然后慢慢一个一个吐出来, \d得到3结束
10 \w*?(\d+) \d匹配2003
11
12
13 慎用点员字符
14
15
16 合理使用字符串函数代替
17
18 合适使用括号 每次使用一次括号,而不是非捕获型括号(?:....)就会保留一部分内存等着再次访问
19
20 起始、行描点优化
21 ^(?:abc|123) 比 ^123|^abc 效率高
22 ^(abc) 比(^abc)效率高
23
24 使用正则以外的解决方案
25 php5 提供 filter函数
26 filter_var('admin@example.com'FILTER_VALIDATE_EMAIL);
27
28 JAVASCRIPT 里面 用DOM代替一些正则匹配
29 php的字符串函数
30 php的 tokenizer 系类函数
31 php的url 函数及一些http函数
32 php的filter 系列函数
33 javascript的dom 模型
正则在实际开发中的应用
1<div>logo</div>
2(?<=<div>).*(?=</div>) //匹配除logo
3m|food 和(m|f)ood的区别 考虑 优先级
4 m 或者food
5 mood 或者food
6
7
8
匹配E-email地址
1 ^[a-z0-9_\-]+(\.[_a-z0-9\-]+)*@([_a-z0-9\-]+\.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel)$
正则匹配中文
1$str = "编程";
2//UTF-8汉字字母数字下划线正则表达式
3if(!preg_match_all("/^[\x{4e00}-\x{9fa5}]+$/u",$str)) //UTF-8汉字字母数字下划线正则表达式
4{
5 echo "<font color=red>您输入的[".$str."]含有违法字符</font>";
6}
7else
8{
9 echo "<font color=green>您输入的[".$str."]完全合法,通过!</font>";
10}