我的问题是如何替换字符串中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>
并终止于{ {1}}第一个>
更改了它之间找到的<img>
属性!
III。通过删除模式末尾的src
元字符,导致s
按预期运行,但在使用enter键断开标记时失败:
$pattern = "%".$start."(.*?)".$property."\s*=\s*[\"\'](.*?)[\"\'](.*?)".$end."%";
IV。当然,我的意图是替换而不是删除<script language="javascript" src= "../tests/ajax-navigation.js"
></script>
属性的值。
希望这些澄清我的问题。
答案 0 :(得分: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前面的反斜杠是做什么的。我也不得不删除它。
答案 1 :(得分: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,同时遵循我使用的<
和>
类似[&lt;] $ start而不是将<
传递给函数的语法。通过在%之后使用相应的preg_match选项或使用之前使用strtolower转换所有数据,还要确保它不区分大小写。我敢肯定,如果这样可行,你可以自己解决问题。
答案 2 :(得分: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);