PHP正则相关

描述字符串排列模式的一种自定义语法规则
如果可以使用字符串函数处理的任务 就不要使用正则
正则表达式 就是通过构建具有特定规则的模式,与输入的字符信息比较 在进行 分割 匹配 查找 替换 等工作
 
 
正则表达式 也是一个字符串
由具有特殊意义的字符串组成的字符
具有一定的编写规则 也是一种模式 
可以把正则表达式看做是一种编程语言(是用一些特殊字符按照规则 编写出一个字符串 然后形成一种模式 --- 正则表达式)
 
 
 
 
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 是每个() 里面的具体属性
例子
  1. Array  
  2. (  
  3.     [0] => Array  
  4.         (  
  5.             [0] => http://bbs.thmz.com/thread-1931127-1-1.html  
  6.   
  7.             [1] => http://bbs.thmz.com/thread-1931127-1-1.html  
  8.            
  9.         )  
  10.   
  11.     [1] => Array  
  12.         (  
  13.             [0] => http  
  14.             [1] => http  
  15.         )  
  16.   
  17.     [2] => Array  
  18.         (  
  19.             [0] => ://bbs.thmz.com/thread-1931127-1-1.html  
  20.             [1] => ://bbs.thmz.com/thread-1931127-1-1.html  
  21.         )  
  22.   
  23. )  
 
 
 
 
 
 
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('匹配内容','替换成什么内容','源','限制替换次数');
但是  正则表达式的子参数 可以用到第二个参数里面
 
 
  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代码
  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代码替换
 
  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.   
  10.   
  11. $htmls = array(  
  12.     '<b>$1</b>','<u>$1</u>','<i>$1</i>','<s>$1</s>',  
  13.     '<font color="$1">$2</font>',  
  14.     '<font size="$1">$2</font>'  
  15.     );  
  16. $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。";  
  17. $n = preg_replace($ubbcode,$htmls,$str);  
  18. echo $n;  
 
 
 
 
 
 
 
 
 
 
 
 
preg_replace_callback  执行一个正则表达式搜索并且使用一个回调进行替换
 
 
分割一个字符串成数组  比原生的explode 更强大
  1. $a = "127.0,0?1";  
  2. print_r(preg_split('/[.,?]/',$a));  
 
 
 
 
 
 
在一个数组里面匹配一组相同的字符,返回一个新数组
  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  来捕获

posted @ 2018-10-29 16:53  梁天  阅读(229)  评论(0编辑  收藏  举报