Я не знаю, если я получаю ваш вопрос совершенно правильно, если вы хотите иметь дело со всеми текстовыми последовательностями, заключенных в src="
и "
, следующий шаблон может сделать это:
~(\ssrc=")([^"]+)(")~
Она состоит из трех групп, захватив из которых вторая одна содержит данные, вы заинтересованы в первый и последний полезно изменить весь матч..
Теперь вы можете заменить все экземпляры функцией обратного вызова, которая меняет места. Я создал простую строку со всеми 6 случаев вы получили:
$site = <<<BUFFER
1. src="//www.stackoverflow.com/cat.png"
2. src="http://www.stackoverflow.com/cat.png"
3. src="https://www.stackoverflow.com/cat.png"
4. src="somedirectory/cat.png"
5. src="/cat.png"
6. src="cat.png"
BUFFER;
Давайте игнорировать на минуту, что нет ни одного окружающей HTML-тегов, вы не разбор HTML в любом случае я уверен, что, как вы не попросили парсер HTML, а для регулярного выражения. В следующем примере совпадение в середине (URL) будет вложено так, чтобы было ясно, что оно соответствует:
Итак, теперь, чтобы заменить каждую из ссылок, давайте начнем легко, просто выделив их в строке.
$pattern = '~(\ssrc=")([^"]+)(")~';
echo preg_replace_callback($pattern, function ($matches) {
return $matches[1] . ">>>" . $matches[2] . "<<<" . $matches[3];
}, $site);
Выход для примера, приведенного тогда:
1. src=">>>//www.stackoverflow.com/cat.png<<<"
2. src=">>>http://www.stackoverflow.com/cat.png<<<"
3. src=">>>https://www.stackoverflow.com/cat.png<<<"
4. src=">>>somedirectory/cat.png<<<"
5. src=">>>/cat.png<<<"
6. src=">>>cat.png<<<"
В качестве способа замены строки должно быть изменено, оно может быть извлечено, так что легче изменить:
$callback = function($method) {
return function ($matches) use ($method) {
return $matches[1] . $method($matches[2]) . $matches[3];
};
};
Эта функция создает обратный вызов замены, основанный на методе замены, который вы передаете в качестве параметра.
Такая функция замены может быть:
$highlight = function($string) {
return ">>>$string<<<";
};
И это называется, как в следующем:
$pattern = '~(\ssrc=")([^"]+)(")~';
echo preg_replace_callback($pattern, $callback($highlight), $site);
Выход остается таким же, это было просто показать, как добыча работала:
1. src=">>>//www.stackoverflow.com/cat.png<<<"
2. src=">>>http://www.stackoverflow.com/cat.png<<<"
3. src=">>>https://www.stackoverflow.com/cat.png<<<"
4. src=">>>somedirectory/cat.png<<<"
5. src=">>>/cat.png<<<"
6. src=">>>cat.png<<<"
Преимущество этого в том, что для функции замены вы только нужно иметь дело с совпадением URL как с одной строкой, а не с регулярным выражением, сопоставляющим массив для разных групп.
Теперь на вторую половину вопроса: как заменить это на обработку определенных URL-адресов, например удаление имени файла. Это можно сделать, проанализировав сам URL и удалив имя файла (basename) из компонента пути. Благодаря добыче, вы можете поместить это в простую функцию:
$removeFilename = function ($url) {
$url = new Net_URL2($url);
$base = basename($path = $url->getPath());
$url->setPath(substr($path, 0, -strlen($base)));
return $url;
};
Этот код использует Pear's Net_URL2 URL component (также доступно через Packagist и Github, ваши пакеты ОС, возможно, это тоже). Он может легко анализировать и изменять URL-адреса, поэтому хорошо иметь работу.
Так что теперь замена делается с новой функцией замены URL файла:
$pattern = '~(\ssrc=")([^"]+)(")~';
echo preg_replace_callback($pattern, $callback($removeFilename), $site);
И результат тогда:
1. src="//www.stackoverflow.com/"
2. src="http://www.stackoverflow.com/"
3. src="https://www.stackoverflow.com/"
4. src="somedirectory/"
5. src="/"
6. src=""
Пожалуйста, обратите внимание, что это в качестве примера. Он показывает, как вы можете это делать с регулярными выражениями. Тем не менее, вы можете также использовать HTML-парсер. Давайте сделаем это фактический HTML фрагмент:
1. <img src="//www.stackoverflow.com/cat.png"/>
2. <img src="http://www.stackoverflow.com/cat.png"/>
3. <img src="https://www.stackoverflow.com/cat.png"/>
4. <img src="somedirectory/cat.png"/>
5. <img src="/cat.png"/>
6. <img src="cat.png"/>
А затем обработать все <img>
"src
" атрибуты с созданной функции замены фильтра:
$doc = new DOMDocument();
$saved = libxml_use_internal_errors(true);
$doc->loadHTML($site, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
libxml_use_internal_errors($saved);
$srcs = (new DOMXPath($doc))->query('//img/@hsrc') ?: [];
foreach ($srcs as $src) {
$src->nodeValue = $removeFilename($src->nodeValue);
}
echo $doc->saveHTML();
Результат затем снова:
1. <img src="//www.stackoverflow.com/cat.png">
2. <img src="http://www.stackoverflow.com/cat.png">
3. <img src="https://www.stackoverflow.com/cat.png">
4. <img src="somedirectory/cat.png">
5. <img src="/cat.png">
6. <img src="cat.png">
Использовался другой способ разбора - замена по-прежнему остается прежней. Просто предложить два разных способа, которые также частично совпадают.
Спасибо - Есть ли способ исправить ссылки, используя ваше решение? – JBithell
@JBithell Он будет работать для всех URL-адресов на странице - a.href, img.src, script.src, link.src и т. Д. –
wow большое спасибо за это хорошо работает ... потрясающе! – sputn1k