【问题标题】:Parsing key-value span pairs with PHP [duplicate]用PHP解析键值跨度对[重复]
【发布时间】:2012-10-25 14:35:29
【问题描述】:

可能重复:
How to parse and process HTML with PHP?

我有一堆代码需要搜索并获取此类数据

<span class="parameter-name-value">
    <span class="parameter-name">....</span> 
    <span class="parameter-value">....</span>
</span>

格式写入 PHP 数组
$array = array(
    array("parameter-name", "parameter-value"),
    array("parameter-name", "parameter-value"),
    array("parameter-name", "parameter-value")
)

我需要什么样的正则表达式?

【问题讨论】:

  • "我需要什么样的正则表达式?" — 不是任何一种。
  • 为什么你的例子中有“参数名称值”,你不使用它
  • @Layke — 问题暗示数据已经存在,而不是只是为了由 PHP 解析而构建的。

标签: php regex parsing html-parsing


【解决方案1】:

这将是您的设置:

function get_tags($string, $start, $end)
{
    $start = str_replace("\\", "\\\\", $start);
    $start = str_replace("/", "\/", $start);
    $end   = str_replace("\\", "\\\\", $end);
    $end   = str_replace("/", "\/", $end);
    preg_match_all("/{$start}(.*?){$end}/si", $string, $matching_data);
    return $matching_data[0];
}

function return_between($string, $start, $stop, $type)
{
    $temp = split_string($string, $start, false, $type);
    return split_string($temp, $stop, true, $type);
}

function get_attribute($tag, $attribute)
{   
    // Remove all line feeds from the string
    $cleaned_html = str_replace("\r", "", $tag);   
    $cleaned_html = str_replace("\n", "", $cleaned_html);

    // Use return_between() to find the properly quoted value for the attribute
    return return_between($cleaned_html, $attribute."=\"", "\"", true);
}

要使用它,像这样:

$open_tag = '<span';
$close_tag = '>';

$span_tags = get_tags($html_string, $open_tag, $close_tag);
$span_tag_class_names = array();

foreach ($span_tags as $key => $tag) {
    $class_name = get_attribute($tag, $attribute = "class");
    if (!empty($class_name)) {
        $span_tag_class_names[] = $class_name;
    }
}

print_r($span_tag_class_names);

与所有正则表达式一样,您的里程可能会有所不同。

【讨论】:

    【解决方案2】:

    如果您知道您的数据将与您呈现的完全一样,并且永远不会改变,那么使用正则表达式比加载 XML 库更快更容易。但请记住,无需进行太多更改即可使其失败。 XML 解析器解决方案更加健壮。

    $data = '<span class="parameter-name-value">
        <span class="parameter-name">A</span>
        <span class="parameter-value">x</span>
    </span>
    <span class="parameter-name-value">
        <span class="parameter-name">B</span>
        <span class="parameter-value">y</span>
    </span>
    <span class="parameter-name-value">
        <span class="parameter-name">C</span>
        <span class="parameter-value">z</span>
    </span>
    ';
    
    $pattern = '@<span class=\"parameter-name-value\">
        <span class=\"parameter-name\">(.*)</span>
        <span class=\"parameter-value\">(.*)</span>
    </span>@';
    
    preg_match_all($pattern, $data, $matches);
    list($_, $keys, $values) = $matches;
    $result = array_combine($keys, $values);
    print_r($result);
    

    输出

    Array
    (
        [A] => x
        [B] => y
        [C] => z
    )
    

    【讨论】:

    • 干净+1。但我会在标签之间使用\s* 以实现更灵活的匹配,并使用(.*?)(带有惰性量词)进行捕获和单行s 修饰符以允许值中的换行符。
    • 抱歉,这不起作用。跨度不直接在彼此之后列出。
    • @MikkoP 你能举个例子说明它在哪里不起作用吗?把任何东西放在中间应该不是问题。
    【解决方案3】:

    你的HTML不清楚但可以使用DOMDocument不管格式

    $html = '<span class="parameter-name-value">
        <span class="parameter-name">A</span> 
        <span class="parameter-value">1</span>
    </span>
    <span class="parameter-name-value">
        <span class="parameter-name">B</span> 
        <span class="parameter-value">2</span>
    </span>';
    
    $dom = new DOMDocument();
    $dom->loadHTML($html);
    
    $xpath = new DOMXPath($dom);
    $span = $xpath->query("//span/span");
    
        $dom = new DOMDocument();
    $dom->loadHTML($html);
    
    $xpath = new DOMXPath($dom);
    $span = $xpath->query("//span/span");
    
    $list = array();
    $list2 = array();
    
    for($i = 0; $i < $span->length; $i += 2) {
        $name = $span->item($i);
        $value = $span->item($i + 1);
        $list[] = array($name->getAttribute('class') => $name->nodeValue,$value->getAttribute('class') => $value->nodeValue);
        $list2[] = array($name->getAttribute('class'),$value->getAttribute('class'));
    }
    
    var_dump($list);
    var_dump($list2);
    

    输出$list

    array
      0 => 
        array
          'parameter-name' => string 'A' (length=1)
          'parameter-value' => string '1' (length=1)
      1 => 
        array
          'parameter-name' => string 'B' (length=1)
          'parameter-value' => string '2' (length=1)
    

    输出$list2

    array
      0 => 
        array
          0 => string 'parameter-name' (length=14)
          1 => string 'parameter-value' (length=15)
      1 => 
        array
          0 => string 'parameter-name' (length=14)
          1 => string 'parameter-value' (length=15)
    

    【讨论】:

    • 很好,但是getAttribute 函数是什么? Fatal error: Call to a member function getAttribute() on a non-object
    • 使用你给我的 XML codepad.viper-7.com/ppUOyf 它可以工作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多