Моя проблема заключается в том, как заменить значение 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. regex $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>
внутривенно и, конечно, я намерен заменить и не удалять значение в свойстве src
.
Надеюсь, это разъяснит мой вопрос.
Измените эту строку:
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. Мне тоже пришлось снять это.
Вот код, который я использовал, чтобы найти все элементы с 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 все, следуя синтаксису, который я использовал, ставя <
и >
как [<] $ start вместо передачи <
в функцию. Также убедитесь, что он не чувствителен к регистру, используя соответствующие параметры preg_match после% или конвертируя все данные, используя strtolower раньше. Я уверен, что если это сработает, вы сами сможете понять остальное.
Как я уже сказал, я буду использовать 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);
Я использовал ответ Эмануэле Дель Гранде из этого поста, который может быть воспроизведением таких сообщений!
Благодарю.