2009-07-05 37 views
7

Tôi đã có một chuỗi với thuộc tính HTML:PHP - chia một chuỗi của HTML thuộc tính thành một mảng được lập chỉ mục

$attribs = ' id= "header " class = "foo bar" style ="background-color:#fff; color: red; "'; 

Làm thế nào để chuyển đổi chuỗi thành một mảng được lập chỉ mục, như:

array(
    'id' => 'header', 
    'class' => array('foo', 'bar'), 
    'style' => array(
    'background-color' => '#fff', 
    'color' => 'red' 
) 
) 

vì vậy tôi có thể sử dụng hàm array_merge_recursive PHP để hợp nhất 2 tập hợp các thuộc tính HTML.

Cảm ơn bạn

Trả lời

8

Bạn có thể sử dụng một biểu thức chính quy để trích xuất thông tin rằng:

$attribs = ' id= "header " class = "foo bar" style ="background-color:#fff; color: red; "'; 
$pattern = '/(\\w+)\s*=\\s*("[^"]*"|\'[^\']*\'|[^"\'\\s>]*)/'; 
preg_match_all($pattern, $attribs, $matches, PREG_SET_ORDER); 
$attrs = array(); 
foreach ($matches as $match) { 
    if (($match[2][0] == '"' || $match[2][0] == "'") && $match[2][0] == $match[2][strlen($match[2])-1]) { 
     $match[2] = substr($match[2], 1, -1); 
    } 
    $name = strtolower($match[1]); 
    $value = html_entity_decode($match[2]); 
    switch ($name) { 
    case 'class': 
     $attrs[$name] = preg_split('/\s+/', trim($value)); 
     break; 
    case 'style': 
     // parse CSS property declarations 
     break; 
    default: 
     $attrs[$name] = $value; 
    } 
} 
var_dump($attrs); 

Bây giờ bạn chỉ cần phải phân tích các lớp học của class (split tại khoảng trắng) và tờ khai tài sản của style (một khó hơn một chút vì nó có thể chứa các chú thích và URL với ; trong đó).

+0

Cảm ơn bạn Gumbo, regex của bạn mát mẻ. Vấn đề duy nhất là $ attrs ['class'] hoặc $ attrs ['style'] đang trả về chuỗi: vì vậy sẽ rất khó hợp nhất chúng với chuỗi $ attribs khác, ví dụ: kết hợp 2 bộ attribs: $ attribs1 = 'class = "foo bar"'; $ attribs2 = 'class = "lorem"'; vào một 'class = "foo bar lorem"' Đó là lý do tại sao tôi muốn $ attrs ['class'] trả về mảng: mảng ('foo', 'bar') Bạn có ý tưởng để nâng cao điều này không ? – abernier

+0

Tôi thực sự yêu thích giải pháp này ... nhưng tôi không nhận được regex xD nó hơi nhiều cho đầu của tôi – lumio

+1

Tôi vừa viết một regex thay thế cũng phân tích các thuộc tính boolean kiểu HTML5 (không có dấu =) và sử dụng tham chiếu ngược cho dấu ngoặc kép: '(\ w +) \ s * (= \ s * ([" ']) (. *?) \ 2 \ s)? ' –

2

Có thể điều này giúp bạn .. Những gì nó ..

  • Một HTML DOM phân tích cú pháp viết bằng PHP5 + cho phép bạn thao tác HTML trong một cách rất dễ dàng!
  • Yêu cầu PHP 5+.
  • Hỗ trợ HTML không hợp lệ.
  • Tìm các thẻ trên trang HTML có bộ chọn giống như jQuery.
  • Trích xuất nội dung từ HTML trong một dòng.

http://simplehtmldom.sourceforge.net/

+0

Lưu ý rằng một lý do tôi kết thúc ở đây là bởi vì DOMProcessingInstruction có một trường 'data', đó là văn bản wihin' ' Trong trường hợp của một thẻ như: '' bạn nhận được một chuỗi đơn giản như: 'type =" text/xsl "href =" https://sms.m2osw.com/sitemap.xsl "' –

3

Bạn không thể sử dụng một biểu thức chính quy để phân tích html-thuộc tính. Điều này là do cú pháp là theo ngữ cảnh. Bạn có thể sử dụng các biểu thức chính quy để mã hóa đầu vào, nhưng bạn cần một máy trạng thái để phân tích nó.

Nếu hiệu suất không phải là vấn đề lớn, cách an toàn nhất để thực hiện, có lẽ là bọc các thuộc tính trong thẻ và sau đó gửi nó thông qua trình phân tích cú pháp html. Eg .:

function parse_attributes($input) { 
    $dom = new DomDocument(); 
    $dom->loadHtml("<foo " . $input. "/>"); 
    $attributes = array(); 
    foreach ($dom->documentElement->attributes as $name => $attr) { 
    $attributes[$name] = $node->value; 
    } 
    return $attributes; 
} 

Bạn có thể có thể tối ưu hóa trên, bằng cách tái sử dụng phân tích cú pháp, hoặc bằng cách sử dụng XmlReader hay sax parser.

+0

Phân tích cú pháp này: foo = 'bar' cuux = "O'Reiley" zip = "\" zap \ "" – troelskn

+0

@troelskn: Khai báo giá trị thuộc tính thứ ba không hợp lệ. được thể hiện bằng các tham chiếu ký tự. – Gumbo

+0

Bạn nói đúng - Tôi không biết điều đó. Tôi vẫn sẽ đề nghị sử dụng một trình phân tích cú pháp xml/html, để giải thích cho tất cả các trường hợp cạnh lẻ. – troelskn

17

Sử dụng SimpleXML:

<?php 
$attribs = ' id= "header " class = "foo bar" style ="background-color:#fff; color: red; "'; 

$x = new SimpleXMLElement("<element $attribs />"); 

print_r($x); 

?> 

này giả định rằng các thuộc tính luôn tên/cặp giá trị ...

1

Cách dễ dàng có thể thêm:

 
$atts_array = current((array) new SimpleXMLElement("<element $attribs />")); 
Các vấn đề liên quan