进一步的去了解正则[一]

1 正则是什么.
  请先看 http://www.phpchina.com/html/11/n-34811.html 几k 的解释后.

原地址已被更改,重新找了一个教程,请点击。 http://deerchao.net/tutorials/regex/regex.htm

2 实例剖析.
1.    $str = '<FORM&NBSP;NAME="ADFA"&NBSP;ACTION="ASDF.BPHP"&NBSP;TARGET=""><FORM&NBSP;NAME="BBBB"&NBSP;ACTION="HTTP: www.bac.com test.php? target="qwerqwerq"><FORM&NBSP;NAME="BBBB"&NBSP;ACTION="HTTP.PHP"&NBSP;TARGET="QWERQWERQ">'; 
2.        $match = ''; 
3.        preg_match_all('//s+action=/"(?!http:)(.*?)/"/s/', $str,       $match); 
4.        print_r($match);
//s+action=/"(?!http:)(.*?)/"/s/ 此正则是用来匹配 action=”xxx” 里面的xxx的.
可讲的地方有3
1  /”(.*?)/” 会匹配  aa”abb”aaaa”  字符串中的”abb””  而(.*)/” 则会去匹配aa”abb”aaaa”中的”abb”aaaa”. 此谓之贪婪(greedy) 特别实用。U 修正符可以反转正则式中的贪婪。
2 (?!http:) 代表将要匹配的内容中不含有http: 他本身不匹配内容.
例如 我要匹配一个 长为8-16里面不能有http 的字符串,就写 (?!http)/w{8-16} 即可。
3 就是这哥们匹配时,定死了action=” 后面的这个(“) 如果是 ‘ 号呢怎么办呢?
这里就要用到 反向引用了。
相关正则表达式如下。
(?<=/s*action=('|/"))(?!|http)(.*?)(?=/1)
  演化一下
最初的想法
  Action=/”(.*)/”  => 为能只匹配 action=”dddd” fdsfds” 中的action=”dddd”而不是action=”dddd” fdsfds” 更改为action=/”(.*?)/” =>要支持单引号action=(‘/”)(.*?)/1 => action 后面引号内不允许有http  action=(‘/”)(?!http:)(.*?)/1  => 只想提取引号内的内容,不想提取其它的内容. (?<=/s*action=('|/"))(?!http)(.*?)(?=/1)

文中还有两个例子挺实用的。
带断言的正则匹配
1.    $match = ''; 
2.       $str = '<A&NBSP;HREF="">xxxxxx.com.cn <b>ddddbolod</b>paragraph text
'; 
3.       preg_match_all ( '/(?<=<(/w{1})>).*(?=<///1>)/', $str, $match ); 
4.       echo "<BR&NBSP; />匹配没有属性的标签中的内容:"; 
5.       print_r ( $match );
正则式为(?<=<(/w{1})>).*(?=<///1>)
(?<=<(/w{1})>) 为逆向预匹配,就是说需要匹配的左边要满足这要求。
上php手册查了一下,preg_match_all("/(<([/w]+)[^>]*>)(.*?)(<2>)/", $html, $matches, PREG_SET_ORDER);

然后表大式可以更改为(?<=<(/w+)>).*(?=<///1>)
替换HTML源码中的地址  
1.    $form_html = preg_replace ( '/(?<=/saction=/"|/ssrc=/"|/shref=/")(?!http:|javascript)(.*?)(?=/"/s)/e', 'add_url(/$url, /'//1/')', $form_html );
这个也是单双引号的问题,需要改改.

2 看完帖http://www.phpchina.com/html/03/n-34203.html
觉得
function is_good_pw($pw) {
    if(preg_match('/(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}/', $pw)) {
        return true;
    }
    return false;
}
可以吸收一下。下面我决定啰哩啰嗦的解试一下这个函数。
.{8-16} 代表匹配8-16位非换行字符串。
可是当我们需要这8-16 位的数字中,必须有数字,而且有小写字母,而且有大写字母时,正则表达式如何去写呢?

 (?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}
匹配 必须有数字,小写字母,大写之母的 的8-16 位的字符.
1 基础概念讲解.
  1 理解缝隙的概念.
    例如, "^","$","/b"。它们都有一个共同点,那就是:它们本身不匹配任何字符,只是对 "字符串的两头" 或者 "字符之间的缝隙" 附加了一个条件
 2  ?=xxx) 正向预搜索 代表缝隙的右侧,必须能够匹配上 xxxxx 这部分的表达式
 
那么
(?=.*[/d]).{8-16} 代表匹配含有数字的8-16位的字符串,
如果是(?=/d).{8-16}则匹配的内容为首位为数字的8-16 的字符串.
如果是(?=/d{2}).{8-16}则匹配的内容为前两位为数字的8-16 的字符串.
从这里看来,正向预搜索需要理解的就是(?=xxx) 本身是不匹配字符的,而是给右侧的字符串添加条件,目的就是要右侧的字符串能满足这个预搜索条件。

.{8-16}  代表任意非换行的8 位字符串.
(?=.*[/d]).{8-16} 代表任意非换行的8-16 位字符串,而且这8-16位字符串中有数字。
(?=.*[/d]) (?=.*[a-z]).{8-16}代表任意非换行的8-16 位字符串,而且这8-16位字符串中有数字,而且这8-16位字符串中有a-z 之间的字母.
这样看来(?=.*[/d]).{8-16}的(?=.*[/d])就是用来向.{8-16}来叠加规则的.*[/d] 的
(?=.*[a-z]) (?=.*[/d]).{8-16} 中的(?=.*[a-z])就是用来向(?=.*[/d]).{8-16}叠加(?=.*[a-z])规则。
这样下来,当我们需要匹配的8-16位中间有数字而且有大写字母而且有小写字母,的时修就用到了(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z]).{8,16}

此时,我们能匹配8-16 位的数字中,必须有数字,而且有小写字母,而且有大写字母
这时,如果要被匹配的字符串中不能出现 http 这时怎么处理呢?
答案很简单 加个正向否定预搜索就可以了
(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?!http).{8,16}

下一个实例,货币替换.
1 理清思路,
货币替换对正则而言就是要找那些 距离结尾或[.] 隔着/d{3}+ 的/d
所以一开始就是(/d)(?=(/d{3})+($|/./d*))
如果不希望回代后面的值,就用(/d)(?=(?:/d{3})+(?:$|/./d*))
再补点预搜索条件(?=/d)(?!/./d*) 是数字,而且不能以 .开头 最后就拼接成了.
(?<!/./d*)(?=/d)(/d)(?=(?:/d{3})+(?:$|/./d*))
附php代码.




<?php
$money_arr =  array(
    "0",
    "12",
    "123",
    "1234",
    "12345",
    "123456",
    "1234567",
    "123456789",
    "1234567890",
    "12.345",
    "123.456",
    "1234.56",
    "12345.6789",
    "123456.789",
    "1234567.89",
    "12345678.9",
    "sdsd12345678.9"
);
 
foreach($money_arr as $key=>$val)
{
    echo $val;
    $str = preg_replace("/(?=/d)(?!/./d*)(/d)(?=(?:/d{3})+($|/./d*))/","$1,",$val);
    echo "the replace result is";echo $str;
    echo "<hr/>";
}

function pr($arr){ //格式化输出数组.
    print("<pre>");print_r($arr);print("</pre>");
}
?>

下一例:
<img src=’xxx’>
<img src=’xxx’ />
<img src=’xxx’ > ddd</img>
当需要抓取这三种时,第三种的前面和第一种重复,则用 ? 来解决
<img[^>]>(.*<//img>)? 即可

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值