描述字符串排列模式的一种自定义语法规则

如果可以使用字符串函数处理的任务 就不要使用正则

正则表达式 就是通过构建具有特定规则的模式,与输入的字符信息比较 在进行 分割 匹配 查找 替换 等工作



正则表达式 也是一个字符串

由具有特殊意义的字符串组成的字符

具有一定的编写规则 也是一种模式 

可以把正则表达式看做是一种编程语言(是用一些特殊字符按照规则 编写出一个字符串 然后形成一种模式 --- 正则表达式)





waring:  

如果正则表达式 不和函数一起使用,那么他就是一个字符串  如果将正则表达式放入到某个函数中使用 才能发挥出正则表达式的作用



用到分割函数中 就可以用这个去分割

用到替换函数中 就可以用这个去替换

用到匹配函数中 就可以用这个去匹配



在php中有两套php正则表达式  

POSIX  扩展正则表达式函数  ereg_

perl  兼容的正则表达式函数  preg_

这两套函数的功能一样



正则表达式如何编写

  1. 定界符  //

      除了字母 数字 和正斜线 \ 以外的任何字符都可以是定界符  比如 ||   //  {}   ## !!

  2. 原子   img \s .   

      一个正则表达式  可以没有元字符 但是必须至少包含一个原子

      只要一个正则表达式可以单独使用的字符 就是原子

      所有打印字符和费打印字符都是原子

      如果有些元字符 想作为原子使用  统统使用 \  转义字符转义


  3. 元字符   * ? 

      元字符是一个特殊的字符 是用来修饰原子用的 不可以单独出现 

  4. 模式修正符  I U 



/原子和元字符/模式修饰符





========================================

【原子】

\d  代表任意一个数字

\D  任意一个除了数字之外的字符

\s  匹配任意一个空白字符 空格 回车  \n  换行  \r  

\S  匹配任意一个非空白 

\w  匹配任意一个 a-zA-Z0-9_ 

\W  除了a-zA-Z0-9_之外的字符


[]  匹配[]中的任何一个原子 [12345]  里面的正则是或的关系 

        里面的正则元字符没意义   都是当做字符串来表示   

        里面只能单独匹配一个原子  不能匹配多个  

        [^ ] 表示取反



[^] 除了[]里面的所原子之外的字符  取反的意思  [^a-z123]

【元字符】

*   表示本修饰原子的前面的字符可以出现0次或者多次

+   表示前面的字符可以出现1次或者多次

.   表示任意一个字符 除了换行符

^   表示开头必须是前面的字符

$   表示必须以前面的字符结尾

?   表示前面的字符可以出现0次或者1次

|   或者的关系

{}  自定义前面原子出现的次数  {5} 5次 {1,} 最少1次 {1,3} 1到3次

\b  匹配边界  两边如果有边界

\B  匹配非边界

()  作为大原子使用 括号里面的集合 可以看成一个大原子



    1. (abc)+  意思是 abcabcabc 这样

    2. (a|b) 改变优先级 ()里面优先级高

    3. 作为子模式使用

      $reg = "/3+(abc)(t)/";

      $string = "333abct";

      if(preg_match($reg,$string,$arr)) 

      结果是  

      Array ( [0] => 333abct [1] => abc [2] => t )

    4. 反向引用

       取出子模式 再作为正则表达式的一部分 如果是preg_replace 可以将子模式取出 在被替换的字符串使用

      \1  取第一个子模式  。。。。\2\3\4\5

      注意 如果是双引号 那必须是\\ 单引号 就是 \


    5. 取消子模式

      如果只是想用个括号 并不是子模式 可以这么用  (?:)  在括号最前面使用?: 就可以取消这个子模式    

【修饰符】

在定界符后面写模式修正符号

可以一次使用一个也可以使用多个

对正则表达式调优用的 也可以说是对正则表达式的扩展

i  不区分大小写

m  匹配多行  ^..$  多行后任何一行都可以用正则表达式规则套下

s  设置这个.匹配换行

x  表示正则表达式中的空白忽略不计 不是字符串里面的

e  执行php代码

A === ^

Z === $

g 执行一个全局的匹配,简而言之,就是找到所有的匹配 默认只找到一条

/u 表示按unicode(utf-8)匹配(主要针对多字节比如汉字)

U  正则表达式本身就比较贪婪  如果不开启U  正则表达式就会匹配到最后一个   

   禁止贪婪还可以加个?  一样可以禁止贪婪 .*?  如果两个同时出现 那么就会再次开启贪婪模式



正则表达式要转义的字符 

. \ + * ? [ ^ ] $ ( ) { } = ! < > | : - ‘ “





取反

\W                  匹配任意不是字母,数字,下划线,汉字的字符

\S                    匹配任意不是空白的字符

\D                   匹配任意非数字的字符

\B                   匹配不是单词开头或者结束的字符

[^x]                匹配除了X以外的字符

[^aeiou]        匹配除了aeiou这几个字母以外的任意字符



分组、后向引用

    从左往右  以分组的左括号开始 第一个出现的分组是1  第二个是2  以此类推

    分组 0 对应整个正则表达式

    分组号分配要从左往右 扫描两次 第一次是只给未命名的分组分配 第二次给命名分组分配  因此所有命名组的组号都大于未命名组的

    可以使用 (:?   ) 来剥夺一个分组对分组号的分配权

    可以使用 (?<name>)  (?'name') 来自定义组名


    (gwyy)          匹配 gwyy  并且捕获文本到自动命名的组里

    (?<name>gwyy)          匹配gwyy 并且把捕获到的文本命名为name组里 也可以写  (?'name' gwyy)

    (?:gwyy)          匹配gwyy 不捕获文本 也不分配组号


    (?<=gwyy)         匹配gwyy前面的位置

        比如说  gwyyaaa  会返回 aaa


    (?=gwyy)         匹配 gwyy 后面的位置

        比如说  aaagwyy  会返回出 aaa    



    (?!gwyy)         匹配后面跟的不是gwyy的位置



    (?<!gwyy)         匹配前面不是gwyy的位置


    (?#gwyy)          注释






禁止贪婪

    *?  重复任意次 但尽可能少重复

    +?  重复一次或者多次 但是尽可能少重复

    ??  重复零次或者1次 尽可能少重复

   {n,m}?  重复N到M次 尽可能少重复

    {n,}?  重复n次以上 尽可能少重复     





Demo:

  ^\s+$ 用户名不能为空

  [1-9][0-9]{4,12} 匹配腾讯QQ

  (http|https):\/\/(\w)*.(\w)+.(\w)+



采集HTML 最好 不要用 .* 而是用 \s\S

$patth = '/<span class="sTitle">\s+<a href=".*" target="_blank">([\s\S]*)<\/a><\/span>\s+\[(\d+\-\d+)\]/U';



因为HTML会有回车符 和换行符





========================================================



 这个函数是正则表达式匹配函数


preg_match(规则,要匹配的字符串,匹配到的结果集数组,返回数组的模式);





如果匹配成功就返回 true  否则返回 false

匹配到的结果集 第一个是所有的大模式所有的信息 剩下的是按照顺序的一个一个小的子模式 

第三个是一个数组 

可选,存储匹配结果的数组, $matches[0] 将包含与整个模式匹配的文本,$matches[1] 将包含与第一个捕获的括号中的子模式所匹配的文本,以此类推

比如说 有2个()  那么 数组0是所有的()集合  其他的 1、2、3 是每个() 里面的具体属性

例子

[php] ​​view plaincopy​


  1. Array  
  2. (  
  3.     [0] => Array  
  4.         (  
  5.             [0] => http://bbs.thmz.com/thread-1931127-1-1.html  

  6.             [1] => http://bbs.thmz.com/thread-1931127-1-1.html  

  7.         )  

  8.     [1] => Array  
  9.         (  
  10.             [0] => http  
  11.             [1] => http  
  12.         )  

  13.     [2] => Array  
  14.         (  
  15.             [0] => ://bbs.thmz.com/thread-1931127-1-1.html  
  16.             [1] => ://bbs.thmz.com/thread-1931127-1-1.html  
  17.         )  

  18. )  







preg_match_all(规则,要匹配的字符串,匹配到结果数组)  匹配多次 这次的数组是多维数组  

preg_match_all  和 U 的区别一个是匹配一个表达式多次  还有一个是 一个表达式中 所匹配的单位匹配到最近成功的



第四个参数  

PREG_PATTERN_ORDER  默认 结果排序为$matches[0]保存完整模式的所有匹配, $matches[1]保存第一个子组的所有匹配, 以此类推. 



PREG_SET_ORDER    结果排序为$matches[0]包含第一次匹配得到的所有匹配(包含子组), $matches[1]是包含第二次匹配到的所有匹配(包含子组)的数组, 以此类推. 









函数

 字符串的匹配和查找

  preg_match(正则表达式,字符串,返回结果集)



字符串函数有个 

str_repace(替换成的结果,要替换的字符串,源字符串,计算替换几次);

str_replace(字符串,字符串,字符串)

str_replace(数组,字符串,字符串);

str_replace(array,array,string);



正则表达式的替换 

preg_replace('匹配内容','替换成什么内容','源','限制替换次数');

但是  正则表达式的子参数 可以用到第二个参数里面



[php] ​​view plaincopy​


  1. $rel = "/(\w+)/";  
  2. $str = "PHP 独特的语法混合了 C、Java、Perl 以及 PHP 自创的语法。 ";  
  3. $n = preg_replace($rel,'<font color="red">$1</font>',$str);  
  4. echo $n;  




这样就会把所有的 a-z0-0_ 全部替换成了红色   

第二个参数如果调用正则表达式里面的() 你可以用 \1  也可以用 $1



第二个参数是函数的话 要加个修饰符 e 执行php代码

[php] ​​view plaincopy​


  1. $rel = "/(\w+)/e";  
  2. $str = "PHP 独特的语法混合了 C、Java、Perl 以及 PHP 自创的语法。 ";  
  3. $n = preg_replace($rel,'"<font color=\"red\">".strtoupper("$1")."</font>"',$str);  
  4. echo $n;  




还可以在前两个参数中 都使用数组 这样就能同时替换多个了 下面是个ubb代码替换


[php] ​​view plaincopy​


  1. $ubbcode = array(  
  2.     '/\[b\](.*)\[\/b\]/U',  
  3.     '/\[u\](.*)\[\/u\]/U',  
  4.     '/\[i\](.*)\[\/i\]/U',  
  5.     '/\[del\](.*)\[\/del\]/U',  
  6.     '/\[color=#(\w{6})\](.*)\[\/color\]/U',  
  7.     '/\[size=(\d{1,})px\](.*)\[\/size\]/U'  
  8. );  


  9. $htmls = array(  
  10.     '<b>$1</b>','<u>$1</u>','<i>$1</i>','<s>$1</s>',  
  11.     '<font color="$1">$2</font>',  
  12.     '<font size="$1">$2</font>'  
  13.     );  
  14. $str ="HTML3.0规范是由[del]当时刚成立的W3[/del]C于1995年3月提出,提供了很多新的特性,例如表格、文字绕排和复杂数学元素的显示。[color=#FFCC00]虽然它是被设计用[/color]来兼容2.0版本的,但是[b]实现这个标准的工作在当[/b]时过于复杂,在草案于1995年9月过期时,标准开发也因为缺乏浏览器支持而中止了。3.1版从未被正式提出,而下一个[i]被提出的版本是[/i]开发代号为Wilbur的HTML 3.2,去掉了大部分3.0中的新特性,但是[u]加入了很[/u]多特定浏览器,例如Netscape和Mosaic的元素和属性。HTML对数学公[size=24px]式的支持最后成为[/size]另外一个标准MathML。";  
  15. $n = preg_replace($ubbcode,$htmls,$str);  
  16. echo $n;  













preg_replace_callback  执行一个正则表达式搜索并且使用一个回调进行替换



分割一个字符串成数组  比原生的explode 更强大

[php] ​​view plaincopy​


  1. $a = "127.0,0?1";  
  2. print_r(preg_split('/[.,?]/',$a));  







在一个数组里面匹配一组相同的字符,返回一个新数组

[php] ​​view plaincopy​


  1. $a = array('aa  bb','cc','dd','e e ');  
  2. print_r(preg_grep('/\s+/',$a));  




preg_quote  转义正则表达式字符 不用你手工转义了





==============================================================

匹配$_str 返回一个数组 给 $_new_str

返回数组  

0位 表示所有结果

1位 表示第一个子结果

2位 表示第二个子结果



preg_match('//',$_str,$_new_str);

匹配全部

preg_match_all('//',$_str,$_new_str);



反向引用

/(\d)\1(\d)\2/

如果第一个是一个数字 那么 \1这个位置就是一个反向引用  要求第一次出现的数字 在 \1那里继续出现一次 

\1 就代表第一个()里面的引用

如果还有一个的话 就是第二个值表达式的内容在\2出现

可以捕获很多值表达式  也许是99个也许是100多个



捕获 

/(\d)\1(\d)\2/  如果不是在正则表达式里用 就用  $1  $2  来捕获