<?php
$a='/(?<=<(\w+)>).*(?=<\/\1>)/';$str = "<b>afdddddd</b> <p>ffff</p>";preg_match($a,$str,$arr);print_r ($arr);?>运行程序时,出现错误:
Warning: preg_match() [function.preg-match]: Compilation failed: lookbehind assertion is not fixed length at offset 11 in F:\bt\PHPnow-1.5.4\htdocs\xx\test.php on line 6

其实这个程序很简单的一个表达式,如下(?<=<(\w+)>).*(?=<\/\1>)/  的意思说明如下:匹配不包含属性的简单HTML标签内里的内容。(<?(\w+)>)指定了这样的前缀:被尖括号括起来的单词(比如可能是<b>),然后是.*(任意的字符串),最后是一个后缀(?=<\/\1>)。
这样如果前缀实际上是<b>的话,后缀就是</b>了。整个表达式匹配的是<b>和</b>之间的内容,如果是其它的HTML标签也是匹配其之间的内容。

为什么会这样? 这个表达式在C#中却运行正常!!!!! 在微软的那个测试软件Regex Tester 中也运行正常。有人能说一下吗,谢谢?

解决方案 »

  1.   

    是的,php不支持(?<=(正则式))这种前瞻,但是支持(?<=(具体的串))
      

  2.   

    //$a='/(?<=<(\w+)>).*(?=<\/\1>)/';//C#
    $a='/(?<=<(b)>).*(?=<\/\1>)/';//php,匹配b标签
    $str = "<b>afdddddd</b> <p>ffff</p>";

    preg_match($a,$str,$arr);

    print_r ($arr);//Array ( [0] => afdddddd [1] => b )
      

  3.   


    哦,原来了,谢谢。这是说明PHP的正则表达式不如PERL或C# 强大吗?
      

  4.   

    $a='/<(\w+)>.*<\/\\1>/';$str = "<b>afdddddd</b> <p>ffff</p>";preg_match_all($a,$str,$arr);print_r ($arr);Array
    (
        [0] => Array
            (
                [0] => <b>afdddddd</b>
                [1] => <p>ffff</p>
            )
     
        [1] => Array
            (
                [0] => b
                [1] => p
            )
     
    )
      

  5.   

    奥,对不起,我说错了。
    其实perl和php都只能fixed-width,意思是固定宽度 $a='/(?<=<(\w+)>).*(?=<\/\1>)/';//C#
    $a='/(?<=<([\w]{1})>).*(?=<\/\1>)/';//php,这样是可以的。
    $str = "<b>afdddddd</b> <p>ffff</p>";

    preg_match($a,$str,$arr);
      

  6.   

    再纠正一下#1楼。
    php不支持(?<=(不固定宽的正则式))这种前瞻,但是支持(?<=(具体的串))意思是?<=不支持+,*,{1,}啦等等不固定宽的正则式。
      

  7.   

    学习了顺便问一下$a='/(?<=<([\w]{1})>).*(?=<\/\1>)/';//php,这样是可以的
    {1} 里面的是 数字1还是 英文L?有何作用?还有后面的 (?=<\/\1>) 后面的这个1 什么意思?不是 通过 \ 转义了??
      

  8.   

    \w{1}表示长度为1的任意a-zA-z0-9_字符。
    后面的\1表示第一个括号里匹配到的内容。
      

  9.   

    感谢foolbirdflyfirst !!!!  可以结贴了,谢谢。