上字符串:
asd<b=1>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>vv<b=2>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>czxxc求 <b=1>...</b> 内 所有 a的值组成得数组现在我是两步实现:<?php
$s = 'asd<b=1>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>vv<b=2>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>czxxc';
preg_match('/<b=1>.*?<\/b>/', $s, $m);
preg_match_all('/<a=(\d)>/', $m[0],$v);
var_dump($v[1]); // a 所有的值
?>
输出:
array(3) {
  [0]=>
  string(1) "1"
  [1]=>
  string(1) "2"
  [2]=>
  string(1) "3"
}求仅用一次匹配出来.

解决方案 »

  1.   


    preg_match_all('/<b=1>[^<]*<a=(\d+)>[^>]*<a=(\d+)>[^<]*<a=(\d+)>[^>]*<\/b>/iU', $s, $m);  
    print_r($m);Array
    (
        [0] => Array
            (
                [0] => <b=1>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>
            )    [1] => Array
            (
                [0] => 1
            )    [2] => Array
            (
                [0] => 2
            )    [3] => Array
            (
                [0] => 3
            ))
      

  2.   

    试试
    $str = 'asd<b=1>asd<a=1>asdasd<a=2>dsa<a=3>ddd</b>vv<b=2>asd<a=4>asdasd<a=5>dsa<a=6>ddd</b>czxxc';                                                                                  
    $pat = '#(?:<b=1>|\G>)[^<>]+<a=\K\d#';
    preg_match_all($pat,$str,$m);  
    print_r($m);    
    /**
    Array
    (
        [0] => Array
            (
                [0] => 1
                [1] => 2
                [2] => 3
            ))
    */ 
      

  3.   


    你好,foolbirdflyfirst
    关于正则后向引用\K这种方式,能否解释一下怎么使用呢?
    只用过\1,\2...这种后向引用方式,谢谢你。
      

  4.   

    :)
    怎么说呢,这个不算是后向引用,以我的话说就是:轮转式匹配。
    \K : 表示匹配后后面的正则(上面是\d),并找下一个匹配开始
    \G : 表示下一轮匹配开始,以后面那个正则开始(上面是>)
    假若把上面的\G去掉,会匹配所有的<a>,而不是跟着<b=1>的.因为\K后找不到下一轮正确的匹配起始位置
      

  5.   

    对于 K,G这两个好像没什么资料谈及过我觉得这里的正则,要实现在 X和Y之间去寻到具有循环的匹配。
    我尝试用另一种方法去:
    //正则:
    /<b=1>(?:\w*<a=(\d)>\w*)*<\/b>/
    //但不成功,只能获取最后一个 3.
    为什么呢?想不明白。。
      

  6.   

    因为括号里的才推如捕获组。
    比如类似串如:abcd
    那我们知道/(a)(b)(c)(d)/的捕获组是0=>abcd,1=>a,2=>b,3=>c,4=>d,因为有4个()
    那么如果是/(\w)*/,捕获组很容易知道是0=>abcd,1=>a,这个*具体match的东西是不推入捕获组的,否则肯定很影响效率啊,这里只有4个字符,如果你捕获到成千上万个字符,难道一个个都推入捕获组么?/<b=1>(?:\w*<a=(\d)>\w*)*<\/b>/
    第一次match到1,推入$1
    第二次match到2,还是推入$1
    第三次match到3,依然推入$1
    因为你整个正则式只有一对捕获的()啊,(?:..)是非捕获
      

  7.   


    恩,嘿嘿,只知道是被覆盖,原来是这样。thanks。
    另外jordan的写法也不完善,如果<a=\d>的数量多一个,那么可能就匹配不到了。
      

  8.   

    sorry
    ==============================
    那么如果是/(\w)*/,捕获组很容易知道是0=>abcd,1=>d
      

  9.   

    谢谢foolbirdflyfirst,正则学的这么好
      

  10.   

    哈哈,看到foolbirdflyfirst
    想起鸟哥linux私房菜。弱弱地问一句:为啥都是bird?纯属玩笑,莫见怪
      

  11.   

    比不了鸟哥大大,哥永远是菜鸟,这点毋庸置疑啊。
    比如昨天折腾了一天才把android开发配置好,一个按下F2的就解决的问题搞了半天,真想把电脑砸了。
      

  12.   

    在研究android开发了啊。准备转行了? 
      

  13.   


    学习了~..我改了下, 大脑又堵塞了...字符串如果是$s = '
    asd
    <b=1>
    a<c>b<d><b>das<a>
    <a=1>
    <c><d><b>
    <a=2>
    dsa</bb>
    <a=3>
    ddd<dsa></a>
    </b>
    vv
    <b=2>asd<a=4>asdasd<a=5>dsa<a=6>ddd</b>czxxc';
    这个中间又有<>
    依然求<b=1>...</b> 中间的<a=\d>值
      

  14.   

    我的正则是
    /<b=1>(?:\w*<a=(\d)>\w*)*<\/b>/
    第一个 () 是非捕获
    第二个是 捕获的(在非捕获里嵌套了)
    非捕获的我己经让他进行多次循环匹配了。就是这里不明白
    如果不循环,那获取结果只有最后一个(3)是无可否认。
      

  15.   

    吃过早餐脑子好使点了...
    <?php
    $s = '
    asd
    <b=1>
    a<c>b<d><b>das<a>
    <a=1>
    <c><d><b>
    <a=2>
    dsa</bb><<<s<<<>>>>>><<asd><a>,
    <a=3><b=><//b>xcv
    <a=4>xcv,..<><a=9
    <a=a>
    <a=5>xcv,<<a=123>
    ddd<dsa></a>
    </b>
    vv
    <b=2>asd<a=6>asdasd<a=7>dsa<a=8>ddd</b>czxxc';$p = '/
    (?:<b=1>|\G)
    (?:
        <(?!\/b>)[^<]*?
        |
        [^<]*?
    )*?
    <a=\K(\d)>/six';preg_match_all($p,$s,$m);  
    print_r($m[1]);
    /*
    Array
    (
        [0] => 1
        [1] => 2
        [2] => 3
        [3] => 4
        [4] => 5
    )
    */成功匹配<b=1>...</b>中的<a=\d>.
    正则真让人心力交瘁额...
    谢谢各位大侠.