preg_replace_callbackの変数の扱いについて

このQ&Aのポイント
  • preg_replace_callbackを使用して、<a>タグ内のURLの字数を制御するコードに取り組んでいます。
  • shorten(カスタム関数)に渡されるデータが配列なのですが、処理方法がわからず困っています。
  • どのように処理を行い、正常に戻り値を返すことができるでしょうか?
回答を見る
  • ベストアンサー

preg_replace_callback が渡す変数の扱い

preg_replcace_callback を使用して、<a>タグ内のURLの字数を制御するコードに取り組んでいます。詳しい方アドバイスしてくださると助かります。 下のコードの、shorten(カスタム関数)に渡されるデータが配列なのですが、並列に並んだ配列のようなのです。echo をかけてみると、ArrayArray と表示されます。しかし、Array([0]=>Array [1]=>Array) ではないので、どうやって 処理をかけて return すればよいのか途方にくれています。 もしよい方法をご存知の方おられましたらどうぞよろしくお願いいたします。 <? $str = <<<HERE //長いURLのサンプルです。ここの掲示板の処理で途中で表示がカットされていますが、<a href="http://長いURL">http://長いURL</a>という構成になっています。 <a href="http://gooooooooooooooooooooooooooooooooooogle.co.jp">http://gooooooooooooooooooooooooooooooooooogle.co.jp[</a> <a href="http://yahooooooooooooooooooooooooooooooooooo.co.jp">http://yahooooooooooooooooooooooooooooooooooo.co.jp</a> HERE; $pattern = "#<a(.*?)>(.*?)<\/a>#s"; $str = preg_replace_callback($pattern, 'shorten', $str); echo $str; function shorten($matches) { foreach($matches as $index => $match) { if (strlen($match) > 20) { $matches[$index] = substr($match, 0, 20) . '....'; } } return $matches; } ?>

  • jyuu
  • お礼率83% (553/665)
  • PHP
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

>echo をかけてみると、ArrayArray と表示されます。 function shorten($matches) { var_dump($matches); // 変数のダンプをする ・・・ とすると、shorten関数に渡ってきたデータの構造がわかります。 このデータは配列で、$matches[0]はパターン全体にマッチした文字列、$matches[1]はパターン内の1番目の()にマッチした文字列、$matches[2]はパターン内の2番目の()にマッチした文字列、、、となります。 returnするのは文字列です。returnした文字列によって、パターン全体にマッチした部分が置き換わります。この例で、「hogehoge」をリターンすると、「<a href="url">url</a>」が「hogehoge」に置き換えられます。 PHPマニュアルに、もっと詳しい説明や例が載っています。 http://www.php.net/manual/ja/function.preg-replace-callback.php

jyuu
質問者

お礼

ありがとうございます。マニュアルは一通り目を通しました。しかし、マッチが格納されている変数が複数の配列を含んでいるケースは見当たらなかったのですがこちらの見落としでしょうか? print_r($matches)を関数内で行った結果、 Array ( [0] => <a href="URL1">URL1</a> [1] => href="URL1" [2] => URL1 ) Array ( [0] => <a href="URL2">URL2</a> [1] => href="URL2" [2] => URL2 ) とでました。URL1、2はそれぞれ違うhttp://形式のURLです。 これをどのようにして返せばよいのでしょうか? $pattern = "#<a(.*?)>(.*?)<\/a>#s"; $str = preg_replace_callback($pattern, 'shorten', $str); echo $str; function shorten($matches) { if (strlen($matches[2]) > 20) { $matches[2] = substr($matches[2], 0, 20) . '....'; } return $matches; } としても、ArrayArray と表示されます。

関連するQ&A

  • preg_replace 後方参照

    preg_replace関数の外で後方参照を行うことはできないですか? $str = '1234abcde' $str = preg_replace("/^(\d+)/", "", $str); この結果は、$str = 'abcde' ですが、()内の数字つまり1234をpreg_replaceの外で確認するには、 $matches = array(); if(preg_match("/^(\d+)/", $str, $matches)){  $str = preg_replace("/^\d+/", "", $str);  $tmp = $matches[1]; //参照 } という風にpreg_matchと併用するしか方法はないのでしょうか? (  perl でいう $str =~ s/^(\d+)//; $tmp = $1; というようなことをしたい。 )

    • ベストアンサー
    • PHP
  • preg_match_allで取得データをDBへ

    質問:preg_match_allで取得したデータをDBへ格納したいです。 記述文 $pattern = "|HREF=.*?\>|"; preg_match_all($pattern,$str,$match); 補足: $pattern で指定範囲を書いてます。 $str には $patternでとってくる参照データ先が入ってきます。 print_r($match); で念のためブラウザに吐き出すと Array ( [0] => Array ( [0] => HREF="AAA"> [1] => HREF="../../../../Top"> 以下省略 取得したい範囲が取れていることは確認できました。 目的は、とってきた [0] => HREF="AAA"> [1] => HREF="../../../../Top"> : =>より先の文字列が、DBの1つのレコードに1つずつ入っていくイメージです。 アドバイスよろしくお願いします。

    • ベストアンサー
    • PHP
  • preg_match()の使い方

    PHPのpreg_match()でメールアドレスが対象のドメインに所属するかどうかをチェックするスクリプトを作成しようと以下を作成しました。 $ptn = preg_quote("abc.co.jp$"); $str = "user1@abc.co.jp"; $cnt = preg_match("/$ptn/", $str, $matches); 予定では上記で$cntに1が入ると考えていたんですが、 0が返ってきてしまいます。 preg_match()の使い方が誤っているのでしょうか? すいませんが、よろしくおねがいします。

    • 締切済み
    • PHP
  • preg_replace() で、 urlencode()

    現在、Wikiのようなものを作ろうとしていて、 文章中に [[文字列]] があった場合、 <a href="文字列">文字列</a> のような形に置き換えたいのですが、 次のようにすると、$strが「マ」などを含んでいる場合にエラーが起こってしまいます。 $str=preg_replace("/\[\[(.+)\]\]/e","'<a href=\"'.urlencode($1).'\">$1</a>'",$str); 「表」なども、もちろんエラーになります。 どのようにすれば良いのでしょうか。 あるいは、そもそも、別の方法で置き換えた方が良いのでしょうか。 また、過去ログ(http://oshiete1.goo.ne.jp/kotaeru.php3?q=1844374)に、 「表」といった\を含む文字列のURLエンコードをする際は、 「EUC」に文字エンコーディングを変換してから行うようにとの回答がありましたが、 以下のようにしてもエラーが起こってしまいます。 $str="表"; $str=urlencode(mb_convert_encoding($str, "EUC-JP", "SJIS")); どのように書けば良いのでしょうか。 合わせて困っております。 ご教授を宜しくお願い致します。 なお、 mbstring.encoding_translation=Off になってます。レンタルサーバーのため、変更できません。

    • ベストアンサー
    • PHP
  • PHPでURLのソースの中から数字の文字列を検索したいのですが

    PHPでURLのソースの中から数字の文字列を検索したいのですが <?php $str = 85%80%78%77%70%60%; $pattern="/[0-9]+(?=%)/u"; mb_internal_encoding("UTF-8"); preg_match_all($pattern,$str,$matches); foreach((array) $matches[0] as $val) { print mb_convert_kana($val,"a")."<br>\n"; //半角にして表示 } ?> この記述で、文字列から80%のような 全角文字で%の前の文字だけを抜き出せました。 そこでURLからデーターを抜き出すべく ////////ソース////// <table> <TR> <TD>あ</TD> <TD><B>88%</B>/TD> </TR> <TR> <TD>す</TD> <TD><B>85%</B>/TD> </TR> ........... </table> 下記のように記述しましたが <?php $html_data = file_get_contents("http://www.1234.com/1234.html"); if (preg_match("/<table\s.*>([\s\S]*)<\/table>/i",$contents,$matches)){ $contents = $matches[1]; } $str = $html_data; $pattern="/[0-9]+(?=%)/u"; mb_internal_encoding("UTF-8"); preg_match_all($pattern,$str,$matches); foreach((array) $matches[0] as $val) { print mb_convert_kana($val,"a")."<br>\n"; //半角にして表示 } ?> しかし、動作しません。 よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • preg_matchで複数一致した場合の処理

    いつも大変お世話になっております。 「Twitpic 等の画像投稿サービスのサムネイル画像の URL」 http://blog.irons.jp/2009/12/23/twitter_thumb_url/ 上記のサイトをそのまま参考にしまして以下のようなことをしようと思っています。 ・テキストに画像サービスのURLが記載されていたらサムネイル画像を表示 ・普通のURLが含まれていた場合は普通のリンクとして表示 ―――――――――――――――――――― $text = "テキスト http://twitpic.com/xxxxxx http://twitpic.com/yyyyyy http://p.twipple.jp/zzzzzz http://example.com/aaaaaa"; $patterns = array( // twitpic array('/http:\/\/twitpic[.]com\/(\w+)/', '<img src="http://twitpic.com/show/thumb/$1" width="150" height="150" />'), // ついっぷる フォト array('/http:\/\/p[.]twipple[.]jp\/([\w]+)/', '<img src="http://p.twipple.jp/show/large/$1" />'), // 通常URL array('/((?<!")https?:\/\/[a-zA-Z0-9\.\/~_?&=%@#!;*:-]+)/', '$1'), ); foreach ($patterns as $pattern) { if (preg_match($pattern[0], $text, $matches)) { $url = $matches[0]; $text= preg_replace($pattern[0], '<a href="'. $url .'" target="_blank">'.$pattern[1]."</a> ", $text); } } echo $text; ―――――――――――――――――――― これを実施しましたところ、 テキスト [twitpic画像xxxxxx] [twitpic画像yyyyyy] [ついっぷる画像zzzzzz] [通常URLのリンクaaaaa] と、表示自体は希望している形に出来ました。 しかし、[twitpic画像yyyyyy]の部分において、画像はyyyyyyが表示されているのですが、リンク先がhttp://twitpic.com/xxxxxxと、一つ目の画像になってしまっているのです。 おそらく、preg_matchでヒットした最初のURLを変換対象にしてしまっていると思うのですが、 preg_match_allにしたり、様々なやり方で工夫したのですが、どうしても解決できなく、質問させて頂きました。 この場合、2つ目の画像のリンク先をhttp://twitpic.com/yyyyyy へ向けるにはどのように修正したらよろしいでしょうか。 何卒宜しくお願い致します。

    • ベストアンサー
    • PHP
  • 正規表現でpreg_系を使ってタグ内は置き換えないようにする方法

    正規表現でpreg_系を使って、半角スペースを&nbsp;に置き換える処理をしたのですが、タグ内のスペースも&nbs;に置き換わってしましました。 タグ内は置き換えないようにするにはどのようにしたら良いでしょうか? データは複数行渡っています。以下はタグが置き換わるので、逆にタグでないものを置き換えたいです。 <?php function test_call($matches){ return str_replace(" ","&nbsp;",$matches[0]); } $data = <<< EOT この横は変換 します。 <a href="http://www.yahoo.co.jp/" target="_blank">タグの半角スペースは変換せず、 この横は変換する。 </a> このタグも変換してはいけません。< br/> EOT; $data = preg_replace_callback('/<("[^"]*"|\'[^\']*\'|[^>])*>[ ]?/', "test_call", $data); var_dump($data); ?>

    • ベストアンサー
    • PHP
  • preg_replace()でマッチ文字列に関数を

    PHPでのpreg_replace()でマッチした文字列に関数を適用したいのですが、上手くいきません。 $str = "hogeHoge"; $pattern = '/(h.ge)/i'; $replacement = strtoupper("$1"); echo preg_replace($pattern, $replacement, $str); // 期待する結果 : HOGEHOGE // 実行した結果 : hogeHoge 根本的に間違っているかもしれませんが、ご指南いただければ幸いです。

    • ベストアンサー
    • PHP
  • htmlソースからアンカータグ内のURLを配列に

    お世話になっております。 file_get_contents()で取得したhtmlファイルのソースにある、アンカータグに設置されている、URLおよび、そのアンカータグに囲まれたテキストを取得して配列に収めたいと考えているのですが、いろいろと調べていても、思うような結果を出せずにいる状況です。 あるサイトにて、以下のようなソースがあり、これをヒントとしているものの、初めて目にする配列の中の配列?に戸惑い、その分解の仕方が分からず、またアンカータグ内に、target="_blank"などの記述があったりすると、配列に収めることが出来なかったりで、対処の仕方がwからずにいる状況です。 $html = ' <ul> <li><a href="http://www.yahoo.co.jp/">Yahoo!JAPAN</a></li> <li><a href="http://jp.msn.com/">MSN</a></li> <li><a href="http://www.google.co.jp/">Google</a></li> </ul> '; $pattern = '/<a href="([^"]+)">(.+?)<\/a>/is'; $match = array(); preg_match_all($pattern, $html, $match, PREG_SET_ORDER); var_export($match); echo "<br><br>"; print_r($match); 知識が乏しく、お恥ずかしいところと思うことろではありますが、アドバイスなど頂戴できれば幸いです。 お忙しいなか恐縮ですが、宜しくお願い申し上げます。

    • ベストアンサー
    • PHP
  • 複数の配列をまとめて昇順で表示

    //商品番号 $pattern1 = "/<b><font color=\"#000000\">(.*)<\/font><\/b>/"; //商品番号(ランダム) preg_match_all($pattern1, $homepage, $matches1); //商品名 $pattern2 = "/<font size=\"2\"><a href=\".*\">(.*)<\/a><\/font>/"; //商品名 preg_match_all($pattern2, $homepage, $matches2); 上記のように、$matches1には商品番号がで$matches2には商品名のデータが入っています。 商品番号:$matches1[1][0] の商品は$matches2[1][0]になります。 商品番号の順番は昇順ではなくユニークな数値がランダムで入っています。 これをひとつの配列にまとめて、商品番号ソートをかけて表示したいのですが。 最終的な表示は 商品番号:商品名 001:りんご 002:バナナ 003:メロン よろしくお願いします。

    • ベストアンサー
    • PHP

専門家に質問してみよう