系统学习下正则表达式。

正则表达式

正则表单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+
2728    ?'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}