0

我的问题是如何在这个例子中替换一个字符串src中的标签的值<script>(好吧,我在标签内属性的更一般场景中需要这个):

$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. 通过删除s模式末尾的元字符,导致$pattern = "%".$start."(.*?)".$property."\s*=\s*[\"\'](.*?)[\"\'](.*?)".$end."%";行为符合预期,但在标签被输入时失败:

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

iv. 而且,当然我的意图是替换而不是删除src财产的价值。

希望这些能澄清我的问题。

4

3 回答 3

0

更改此行:

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

对此:

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

将默认值 '' 添加到 $alias 参数。

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

于 2013-08-01T21:43:13.947 回答
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 all 同时遵循我使用 put<>like [<]$start 的语法,而不是将 the 传递<给函数。还要确保它不区分大小写,方法是在 % 之后使用相应的 preg_match 选项,或者在之前使用 strtolower 转换所有数据。我敢肯定,如果这行得通,你可以自己解决剩下的问题。

于 2013-08-01T21:48:08.443 回答
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);

我使用了 Emanuele Del Grande 在这篇文章中的回答,这可能是这样的帖子的复制品!
谢谢。

于 2013-08-08T14:02:06.693 回答