2009-07-05 25 views
7

に属性の属性:PHP - HTMLの文字列を分割私はHTMLで文字列を持っているインデックス付きの配列

のように、インデックス付きの配列にその文字列を変換する方法
$attribs = ' id= "header " class = "foo bar" style ="background-color:#fff; color: red; "'; 

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

ですから、PHPのarray_merge_recursive関数を使用して2組のHTML属性をマージすることができます。

は、あなたがその情報を抽出するために、正規表現を使用することができ、あなたに

答えて

8

ありがとう:

$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); 

は今、あなただけのstyleclass(空白で分割)のクラスとプロパティ宣言を解析する必要があります(Aそれには;というコメントとURLを含めることができるので少し難しくなります)。

+0

はあなたのガンボ、あなたの正規表現をありがとうクールです。 唯一の問題は$ attrs ['class']または$ attrs ['style']が文字列を返すためです。たとえば、2つの属性セットをマージするなど、別の$ attribs文字列とマージすることは困難です。 $ attribs1 = 'クラス= "fooバー"'; $ attribs2 = 'class = "lorem"'; を 'class = "foo bar lorem"に置き換えます。 $ attrs [' class ']は配列を返します:array(' foo '、' bar ') これを改善するアイデアはありますか? – abernier

+0

私は本当にこの解決策が大好きです...しかし、私は正規表現xDを得られません。それは私の頭のために少しです。 – lumio

+1

私はちょうどHTML5スタイルのブール属性(=記号なし)と'(\ w +)\ s *(= * s)([*])\ 2 \ s)? –

2

は...それは何...これはあなたを助け かもしれませ

    PHP5 +で書かれた
  • A HTML DOMパーサあなたは非常に簡単な方法でHTMLを操作してみましょう!
  • PHP 5以降が必要です。
  • 無効なHTMLをサポートしています。
  • jQueryと同じようにセレクタでHTMLページのタグを検索します。
  • HTMLからコンテンツを1行に抽出します。

http://simplehtmldom.sourceforge.net/

+0

私がここで終わった1つの理由は、 '<?xml-stylesheet type =" text/xsl "href =" DOMProcessingInstructionは '<?name'と'?> 'の間のテキストである' data'フィールドを持っているためです。 'type =" text/xsl "href =" https://sms.m2osw.com/sitemap.xsl "' https://sms.m2osw.com/sitemap.xsl "?>あなたは属性として解析する必要があります。 –

3

あなたは、HTML属性を解析するために、正規表現を使用することはできません。これは文法が文脈的であるためです。正規表現を使用して入力をトークン化できますが、構文解析するには状態マシンが必要です。

パフォーマンスが重要でない場合は、最も安全な方法は、タグ内の属性をラップし、htmlパーサーに送信することです。例えば:

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; 
} 

おそらくパーサを再利用することによって、またはXmlReaderまたはsax parserを使用することにより、上記のを最適化することができます。

+0

これを構文解析する必要があります:foo = 'bar' cuux = "O'Reiley" zip = "\" zap \ "" – troelskn

+0

@troelskn:3番目の属性値の宣言は無効です。文字参照によって表現される。 – Gumbo

+0

あなたは正しいです - 私はそれを認識していませんでした。私はまだ、xml/htmlパーサを使って、あらゆる種類の奇数のエッジケースを説明することを提案します。 – troelskn

17

利用のSimpleXML:この属性は常に名前/値のペアであることを前提としてい

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

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

print_r($x); 

?> 

...

1

簡単な方法も考えられます。

 
$atts_array = current((array) new SimpleXMLElement("<element $attribs />")); 
関連する問題