PHP DOMXPath使用双引号失败,带单引号

时间:2014-10-10 13:00:13

标签: php xpath domxpath

我写了一个小脚本,使用PHP的DOMXPath类从网站中提取信息 我查询<div class="sku" />并对结果执行substring-before。结果包含文本,非中断空格,换行符和更多文本 所以我要做的就是在&nbsp;&nbsp;\r\n之前切断。当我使用以下查询时,它工作正常:

$query = "substring-before(//div[@class='sku'],'\xC2\xA0\xC2\xA0\r\n')";

但是一旦我更改了引号就会失败(这应该没有任何区别):

$query = 'substring-before(//div[@class="sku"],"\xC2\xA0\xC2\xA0\r\n")';

$query = 'substring-before(//div[@class=\'sku\'],\'\xC2\xA0\xC2\xA0\r\n\')';

这怎么可能,我该如何克服这个?

此处的实例:http://codepad.viper-7.com/R1rCaj

2 个答案:

答案 0 :(得分:3)

引号样式有所不同,因为when a string is enclosed in double-quotes PHP will interpret more escape sequences for special characters - 包括您用于非中断空格\xC2\xA0,回车\r和换行符\n的内容。

当您将这些用单引号'\xC2\xA0\r\n'括起来时,就像在后两个查询中一样,PHP将它们视为那些文字字符 - 反斜杠,x,C,2 ......等。


一些额外的语法突出显示可能有助于显示这个,橙色的转义序列:

enter image description here


如果你的字符串已经包含了作为文字字符的转义序列,并且没办法得到纠正的 * ,那你就有点脏了自己更换它们的位置。

这个preg_replace_callback()会处理你的例子中的那种序列,并且扩展到双引号支持的其余转义序列是微不足道的:

// Known good.
$query1 = "substring-before(//div[@class='sku'],'\xC2\xA0\xC2\xA0\r\n')";

// Known bad.
$query2 = 'substring-before(//div[@class=\'sku\'],\'\xC2\xA0\xC2\xA0\r\n\')';

$query2 = preg_replace_callback(
    '/\\\\(?:[rn]|(?:x[0-9A-Fa-f]{1,2}))/',
    function ($matches) {
        switch (substr($matches[0], 0, 2)) {
            case '\r':
                return "\r";
            case '\n':
                return "\n";
            case '\x':
                return hex2bin(substr($matches[0], 2));
            }
    },
    $query2
);

var_dump($query1 === $query2); // Now equal?

输出:

bool(true)

(*实际上,你应该在源头修复此问题。)

答案 1 :(得分:0)

您可以使用simple_html_dom轻松完成此操作 下载:http://sourceforge.net/projects/simplehtmldom/files/ 手动:http://simplehtmldom.sourceforge.net/manual.htm

    <?php
    // include simple html dom library
    include('./lib/simple_html_dom.php');
    $url="http://www.vosteen-shop.de/p-261232-edelstahl-herz-acero-zum-hngen-lnge-10cm-breite-10cm-silber-glanz.aspx";
    // get html in $html var
    $html=file_get_html($url);
    // find your class div.sku (plaintext) or you can get (innertext)
$results=$html->find('div.sku',0)->innertext;
$explode=explode("<b",$results);
$results=trim($explode[0]);
echo $results ;
    ?>