【问题标题】:str_replace failing with specific charactersstr_replace 因特定字符而失败
【发布时间】:2014-02-28 02:51:39
【问题描述】:

运行一个似乎有声音部分的简单 str_replace,但是当我用这些部分运行 str_replace 时,输出不正确。

foreach($x->query("//img") as $node) 
{   
    $absoluteImage = make_absolute($node->getAttribute("src"), $url);
    $iterateImage = str_replace($node->getAttribute("src"), $absoluteImage, $html);   
}

function make_absolute($url, $base) { 

    // Return base if no url
    if( ! $url) return $base;

    // Already absolute URL
    if(parse_url($url, PHP_URL_SCHEME) != '') return $url;

    // Only containing query or anchor
    if($url[0] == '#' || $url[0] == '?') return $base.$url;

    // Parse base URL and convert to local variables: $scheme, $host, $path
    extract(parse_url($base));

    // If no path, use /
    if( ! isset($path)) $path = '/';

    // Remove non-directory element from path
    $path = preg_replace('#/[^/]*$#', '', $path);

    // Destroy path if relative url points to root
    if($url[0] == '/') $path = '';

    // Dirty absolute URL
    $abs = "$host$path/$url";

    // Replace '//' or '/./' or '/foo/../' with '/'
    $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#');
    for($n = 1; $n > 0; $abs = preg_replace($re, '/', $abs, -1, $n)) {}

    // Absolute URL is ready!
    return $scheme.'://'.$abs;
}

该代码用于将 img 标签的 src 部分从相对 URL 替换为绝对 URL 的刮板。 make_absolute 是完成这项工作的函数,它工作正常。当我同时回显 $absoluteImage 和 $node->getAttribute("src") 时,它们都会打印正确的结果。分别是绝对 URL 和相对 URL。但是当我用这两个部分运行 str_replace 函数时,结果是不正确的。请看以下数据:

相对 URL:

<img border="0" src="media/splash/a1.jpg" width="123" height="49">
<img border="0" src="media/splash/a2.jpg" width="136" height="49">
<img border="0" src="media/splash/pixel_clear.gif" width="187" height="1"><br>
<img border="0" src="media/splash/b1.jpg" width="123" height="66">
<img border="0" src="media/splash/b2.jpg" width="136" height="66">
<img border="0" src="media/splash/b3.jpg" width="187" height="66">
<img border="0" src="media/splash/c1.jpg" width="123" height="150">
<img border="0" src="media/splash/c2.jpg" width="136" height="150">
<img border="0" src="media/splash/c3.jpg" width="187" height="150">
<img border="0" src="media/splash/pixel_clear.gif" width="123" height="1">
<img border="0" src="media/splash/d1.jpg" width="136" height="127">
<img border="0" src="media/splash/d2.jpg" width="187" height="127">
<img border="0" src="media/splash/pixel_clear.gif" width="446" height="59">
<img border="0" src="media/splash/f1.jpg" width="446" height="147"><br>
<img border="0" src="media/splash/g1.jpg" width="446" height="142"></td>

生成的绝对 URL:

<img border="0" src="http://www.bjnormand.com/media/splash/a1.jpg" width="123" height="49">
<img border="0" src="http://www.bjnormand.com/media/splash/a2.jpg" width="136" height="49">
<img border="0" src="http://www.bjnormand.com/http://www.bjnormand.com/http://www.bjnormand.com/media/splash/pixel_clear.gif" width="187" height="1"><br>
<img border="0" src="http://www.bjnormand.com/media/splash/b1.jpg" width="123" height="66">
<img border="0" src="http://www.bjnormand.com/media/splash/b2.jpg" width="136" height="66">
<img border="0" src="http://www.bjnormand.com/media/splash/b3.jpg" width="187" height="66">
<img border="0" src="http://www.bjnormand.com/media/splash/c1.jpg" width="123" height="150">
<img border="0" src="http://www.bjnormand.com/media/splash/c2.jpg" width="136" height="150">
<img border="0" src="http://www.bjnormand.com/media/splash/c3.jpg" width="187" height="150">
<img border="0" src="http://www.bjnormand.com/http://www.bjnormand.com/http://www.bjnormand.com/media/splash/pixel_clear.gif" width="123" height="1">
<img border="0" src="http://www.bjnormand.com/media/splash/d1.jpg" width="136" height="127">
<img border="0" src="http://www.bjnormand.com/media/splash/d2.jpg" width="187" height="127">
<img border="0" src="http://www.bjnormand.com/http://www.bjnormand.com/http://www.bjnormand.com/media/splash/pixel_clear.gif" width="446" height="59">
<img border="0" src="http://www.bjnormand.com/media/splash/f1.jpg" width="446" height="147"><br>
<img border="0" src="http://www.bjnormand.com/media/splash/g1.jpg" width="446" height="142">

我唯一能看到的是失败的 3 行在图像名称中有一个“_”。

有人知道发生了什么吗?

更新: 尝试这样做以密切关注每次迭代,但还没有运气:

$count = 0;
$imgArr = array();
foreach($x->query("//img") as $node) 
{
    if ($node->getAttribute("src")) {
        $imgArr[] = $node->getAttribute("src");
        $count++;
    }
}
for($i = 0; $i < count($imgArr); $i++) {
    $html = str_replace($imgArr[$i], make_absolute($imgArr[$i], $url), $html);
}

echo $html;

【问题讨论】:

  • 在我看来,您的 make_absolute() 函数生成的路径不正确。你能把它的代码贴出来吗?
  • 当然,请参阅更新的代码。不过,正如我提到的,我已经重复了 str_replace 的两个组件,它们都打印出来完全准确。
  • 我没有,主要是因为我已经有了函数中相对到绝对字符串的正则表达式。那,并且避免编写任何不必要的正则表达式

标签: php regex xpath


【解决方案1】:

每次执行循环时,您都会在整个 HTML 块上运行字符串替换。因为您有多次出现相同的图像,所以每次您在循环中点击相同的图像时它都会被替换。

一种解决方案是更改它以包含属性周围的引号,以便它只匹配完整的图像名称:

$iterateImage = str_replace('"'.$node->getAttribute("src").'"', '"'.$absoluteImage.'"', $html);

另一种选择是跟踪您已完成替换的图像,并确保您只为每个图像执行一次替换。但是,如果您有一个图像的名称是另一个图像名称的一部分(例如 image.jpgmyimage.jpg,您可能仍然会遇到问题。

【讨论】:

  • 您的答案适用于这种情况,但如果 src 只被一个引号包围或没有引号,它就会失败。认为除了 str_replace 之外,它必须以另一种方式完成,才能成为通用解决方案。感谢您的帮助
【解决方案2】:

您可以尝试对任何包含下划线的网址进行快速正则表达式:

// Dirty absolute URL
$abs = "$host$path/$url";

if (preg_match('/(_)/', $url)) $abs = "$url"; 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-06
    • 1970-01-01
    • 2020-02-17
    • 2014-10-01
    • 2017-03-25
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多