[PHP-users 30272] Re: 正規表現でタグの属性値を取り出すには?

ucb.rcdtokyo ucb.rcdtokyo @ gmail.com
2006年 9月 7日 (木) 00:05:43 JST


こんばんは。

もし、単一の正規表現で一気に取り出したいという主旨であればズレちゃってますが。
以下は、いったん開始タグの文字列を取り出した上で、そこからさらに、指定の属性値を取り出すもので、この例では(すべての)AタグのHREF属性値を取り出し、配列に格納しています。

/* ------------------------------------------------------------------ */
$array = array();
if (preg_match_all('/<a\b[^>]*?>/si', $html, $matches)) {
  foreach ($matches[0] as $value) {
    if (false !== $x = get_html_attrib('href', $value)) {
      $array[] = $x;
    }
  }
}
print_r($array);

function get_html_attrib($attrib, $tag)
{
  $regex = "/[\s'\"]$attrib\s*=\s*([^\s'\">]+|'[^']+'|\"[^\"]+\")/si";
  return preg_match($regex, $tag, $matches)?
    preg_replace('/^\s*[\'"](.+)[\'"]\s*$/s', '$1', $matches[1]):
    false;
}
/* ------------------------------------------------------------------ */

例として挙げておられるHTMLに対しては随分冗長ですが、より汎用的に使えるかな、と(ただし、タグの文字列を取り出している箇所は、タグの中途に「>」があるとコケます)。
ちなみに http://www.rcdtokyo.com/pc2m/note/
にあるスクリプトは基本的にこのパターンで属性値を取り出しており、様々なHTMLと格闘(笑)した結果こんな感じでやってます。

また、余談ですが、正規表現が必須なわけではなく、HTMLの各タグの属性を手軽に取り出したいということであれば、TidyやPEARのXML_HTMLSaxが使えるかもしれません。
以下はXML_HTMLSax3の例です。

/* ------------------------------------------------------------------ */
require_once 'XML/HTMLSax3.php';
$parser = new XML_HTMLSax3;
$handler = new MyHandler;
$parser->set_object($handler);
$parser->set_element_handler('openHandler', 'closeHandler');
$parser->parse($html);
print_r($handler->tags);

class MyHandler
{
  var $tags;
  function MyHandler()
  {
    $this->tags = array();
  }
  function openHandler(&$parser, $name, $attribs)
  {
    if (!empty($attribs)) {
      $this->tags[] = array($name => $attribs);
    }
  }
  function closeHandler(&$parser, $name)
  {
  }
}
/* ------------------------------------------------------------------ */

06/09/06 に 小川 洋 | Hiroshi Ogawa<wiredhiro @ ybb.ne.jp> さんは書きました:
> 小川です。こんばんは。
>
> 正規表現で<td>タグの要素と、hrefの属性値を取り出した
> いと思い、下記のようなコードを書きました。
> <td>タグの要素は取り出せるのですが、hrefの属性値「images/
> 1100025001p2.jpg」が取り出せません。
> どなたか、適切なアドバイスをよろしくお願いします。
>
> <?php
> //初期化
> $matches="";
> //文字列全体
> $html='<h1 class="line_h1_ico_land">佐倉 市 井野</
> h1><td><a href="images/1100025001p2.jpg" target="_blank"><img
> src="images/1100025001p1.jpg" border="0"></a></td>あいう<td
> colspan="2">えおか</td><td>きくけ</td><td>こさし</
> td><td>すせそbnnjhgghあああああぴ ここ き</td><td>12345</
> td>';
>
> preg_match_all("!(<a\s.*?\bhref\s*=\s*
> ((\"([^\"]+)\")|[^\'\"\s]+)|
> \'([^\']+)\'[^>]*>)|(<h1\s?(\".*?
> \"|\'.*?\'|[^'\"])*?>(.*?)</h1>)|(<td\s?
> (\".*?\"|\'.*?\'|[^'\"])*?>(.*?)</td>)!",
> $html,$matches);
>
> for($i=0; $i<count($matches[0]); $i++)
> {
>         echo "要素:".strip_tags($matches[0][$i])."<br>";
>         //echo "要素:".$matches[0][$i]."<br>";
> }
> ?>

-- 
(It's always) Under Construction, Baby
http://www.rcdtokyo.com/ucb/


PHP-users メーリングリストの案内