我正在解析输入,即HTML。但是,我需要能够找到所有没有协议的href或src属性,例如http://,https://或ftp://等,当它们不替换它时包含协议和域的变量。
所以我想要
<a href="/_mylink/goes/here">Link 1</a>
<a href="http://site.com/_myotherlink/goes/here">Link 2</a>
返回:
<a href="http://mydomain.com/_mylink/goes/here">Link 1</a>
<a href="http://site.com/_myotherlink/goes/here">Link 2</a>
我可以获得整个href属性,但我似乎无法弄清楚如何只匹配和替换IF它缺少一个协议。我发现[^ 0-9]会以反向/不相反的方式工作,但我发现在使用http:// etc进行尝试时我无法使用它。
编辑:
只是提到它,因为我很明显它是这个问题的“范围”的一部分,我想避免因替换而导致网址编码,因为我使用像{}这样的东西其中一些,我不希望他们有像%7B%7D这样的东西。
答案 0 :(得分:3)
为什么不使用DOM轻松替换这些属性?例如
$domain = 'http://mydomain.com';
$currentPath = '/some/absolute/path/'; // make sure this starts and ends with a forward-slash
$doc = new DOMDocument();
$doc->loadHTML($html);
$xpath = new DOMXPath($doc);
$attrs = $xpath->query('//@href[not(contains(., "://"))]');
foreach ($attrs as $attr) {
$attr->value = sprintf('%s%s%s',
$domain,
$attr->value[0] == '/' ? '' : $currentPath,
htmlspecialchars($attr->value)
);
}
$attrs = $xpath->query('//@src[not(contains(., "://"))]');
foreach ($attrs as $attr) {
$attr->value = sprintf('%s%s%s',
$domain,
$attr->value[0] == '/' ? '' : $currentPath,
htmlspecialchars($attr->value)
);
}
echo $doc->saveHTML();
答案 1 :(得分:2)
实质上,您正在寻找“ not ” - 模式。那将是negative assertion:
(?!http://)
例如,在/href="(?!http://)[^"]+"/
中添加。
或者您可以使用preg_replace_callback
并将其排序。
既然你说“解析”它就是一个主题; HTML遍历的替代方法是phpquery或querypath。然后,您可以使用以下链接遍历所有链接:
foreach (htmlqp($html)->find("a[href]") as $tag) {
if (!strstr($tag->attr("href"), "http://")) {
$tag->attr("href", "$add....");
输出转换显然有点过分。但对任意HTML来说可能是一个更具弹性的选择。