2013-08-01 92 views
0

我的问题是如何在这个例子中更换<script>标签的src值在字符串中一样(当然,我需要这样的属性的更一般的情况下内标签):PHP的preg_replace财产html标签内

$data = <<<EOD 
<script language="javascript" src= "../tests/ajax-navigation.js"></script> 
... 
<img src="../404.jpg" alt="404"> 
... 
EOD; 

我用PHP这样的功能:

class Search{ 
public static function replaceProperty($data, $start, $end, $property, $alias, $limit = -1){ 
    //get blocks formed as: $start $property = "..." $end or $start $property = '...' $end 
    $pattern = "!(".$start."){1}(.*?)".$property."\s*=\s*[\"\'](.*?)[\"\'](.*?)(".$end."){1}!s"; 
    $data = \preg_replace($pattern, "{$start}\${2}{$property}=\"{$alias}\"\${4}{$end}", $data, $limit); 
    return $data; 
} 
} 

我把它叫做是这样的:

$data = Search::replaceProperty($data, "<script", ">", "src", $alias); 

真奇怪的是,<script><img>都变了! 我当然可以这样调用它

$data = Search::replaceProperty($data, "<script", "</script>", "src", $alias); 

但这并不回答一般情况下!

只是为了澄清一些观点与正则表达式:

我。要搜索的实际字符串是:

$data = <<<EOD 
<script language="javascript" src= "../tests/ajax-navigation.js"></script> 
... 
<script language="javascript" type="text/javascript"> 
... 
<img src="../404.jpg" alt="404"> 
... 
EOD; 

ii。正则表达式$pattern = "!(".$start."){1}(.*?)".$property."\s*=\s*[\"\'](.*?)[\"\'](.*?)(".$end."){1}!s";或在最简单的形式$pattern = "%".$start."(.*?)".$property."\s*=\s*[\"\'](.*?)[\"\'](.*?)".$end."%s";(仅3子模式)标识第一<script>预期。但它需要第二<script>并终止在第一<img>>改变任何src财产它之间找到了!

iii。通过在导致$pattern = "%".$start."(.*?)".$property."\s*=\s*[\"\'](.*?)[\"\'](.*?)".$end."%";表现为预期,但失败时,标签与破碎的图案的端删除s元字符进入:

<script language="javascript" src= "../tests/ajax-navigation.js" 
></script> 

IV。当然我的意图是替换而不是删除src属性的值。

希望这些说明我的问题。

+1

我决定使用DOMDocument并在这里发布一个问题:http://stackoverflow.com/questions/18031974/replace-property-of-an-html-tag-with-phps-domdocument – centurian

回答

0

改变这一行:

public static function replaceProperty($data, $start, $end, $property, $alias, $limit = -1){ 

要这样:

public static function replaceProperty($data, $start, $end, $property, $alias='', $limit = -1){ 

添加的默认值 '' 到$别名参数。

还不确定preg_replace前面的反斜杠在那里做什么。我也必须删除它。

+0

感谢您的回答,它似乎我没有很好地解释我的$ alias变量:应该得到任何值,比如$ alias =“这里有一些值”。我的目的是取代不删除src属性! (我的反斜杠表示php的命名空间,因为我所有的代码都在不同的命名空间下) – centurian

0

下面是我用preg_match_all查找某个元素的所有代码,我发现preg_match_all比preg_match更好。

$arr = array(); 
preg_match_all("%[<]script.*?[>](.*?)[<][\/]script[>]%",$f, $arr, PREG_OFFSET_CAPTURE); 
var_dump($arr); 

或者用了preg_replace:

$a = preg_replace("%[<]H3.*?[>].*?[<][\/]H3[>]%", "", $a); 

尝试的preg_match所有,而下面我用把<>像[<] $开始传递<的功能,而不是语法。另外,还要确保它不区分大小写使用%,此前各自的preg_match选项或使用之前转换用strtolower所有数据。我敢肯定,如果这样做可以让你自己找出其他问题。

+0

尝试解决方案... 1)没有为preg_replace()工作... – centurian

0

正如我所说的,我会用DOMDocument()但这里是正则表达式的答案:

class Search{ 

public function __construct(){} 

public static function replaceProperty($data, $tag, $property, $alias, $limit = -1){ 
    //get blocks formed as: <$tag...$property=["|']...["|']...[/>|>] 
    $pattern = '%<\s*'.$tag.'(\s+(\w+)(\s*\=\s*(\'|"|)(.*?)\\4\s*)?)*\s*(\/>|>)%s'; 
    $result = \preg_match_all($pattern, $data, $matches, PREG_PATTERN_ORDER); 
    if(!empty($result)){ 
     $search = array(); 
     $replace = array(); 
     //found them at index = 0! 
     foreach($matches[0] as $i=>$found){ 
     if(($limit >= 0) && ($i >= $limit)) 
      break; 
     if(isset($matches[2]) && isset($matches[5]) && $matches[2][$i] == $property){ 
      $search[] = $found; 
      $replace[] = \str_replace($matches[5][$i], $alias, $found); 
     } 
     } 
     $data = \str_replace($search, $replace, $data); 
    } 
    return $data; 
} 
} 

,并呼吁像这样:

$data = Search::replaceProperty($data, "script", "src", $alias); 

我用埃马努埃莱德尔重创的回答从this后可能是this等帖子的复制!
谢谢。