• ベストアンサー

正規表現で自動リンク後、長いURL表示を丸めたい

お世話になります。 PHP4で作った掲示板を運営しています。 過去ログを参考にし、以下の正規表現で投稿本文中のURLを自動リンクしています。 $text=ereg_replace("(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)","<a href='\\0'>\\0</a>",$text); 今の問題は、長いURLを貼られたときに折り返しされず掲示板のレイアウトが崩れることです。 そこで<a>~</a>間の表示部分だけ規定文字数で丸めたいのですが、なかなか良い方法が思いつきません。 どなたかお知恵を貸してください。 ちなみに応急処置として、親<td>タグに style="word-break:break-all;" を入れています。 でもこれだとIE以外は効果ないので・・・。

  • ntm98
  • お礼率77% (17/22)
  • PHP
  • 回答数4
  • ありがとう数3

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

  • ベストアンサー
noname#9903
noname#9903
回答No.4

書き忘れていました for ($j = 0; $j < strlen($matches[0]); $j++) { のあとに 80文字で制限をかけるのなら if ($j >= 80) { break; } で 文字が80文字で切れると思います。

ntm98
質問者

お礼

preg_replace_callback()という関数があったんですね! 手元のリファレンスに載ってなかったので、正規表現でマッチした文字列を個別に抜き出す方法がわからなかったんですよ。 でもこれで解決しました。 教えていただいたコードを元に、こんな感じでやりたかったことを実現しました。 //----------------------------------------- function MakeURLLink($matches) { $TempURLText = $matches[0]; $maxlen = 30;//丸める文字数 if (strlen($matches[0]) > $maxlen){ $TempURLText = substr($matches[0], 0, $maxlen)."...";//$maxlenで文字列を切って「...」をつける } return "<a href=".$matches[0].">".$TempURLText."</a>"; } $URLFilter ="'(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)'"; echo preg_replace_callback($URLFilter, "MakeURLLink", $text); //----------------------------------------- ereg_replaceで使っていた正規表現をそのまま使うとエラーが出てしまいかなり悩んだんですが、 "(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)" ↓ "'(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)'" のように内側をシングルクォーテーションで括ったら直りました。 おかげで助かりました。 ありがとうございました!

その他の回答 (3)

noname#9903
noname#9903
回答No.3

PHP始めたばかりで 正規表現の使い方知らないので 自分でフィルター部分は書き換えてください。 下記で 折り返しできます。 // the callback function function MakeURLLink($matches) { // as usual: $matches[0] is the complete match // $matches[1] the match for the first subpattern // enclosed in '(...)' and so on $TempURLText = ""; for ($j = 0; $j < strlen($matches[0]); $j++) { if ($j ==0) { $TempURLText = $matches[0][0]; } else { if ($j % 3 !=0) // ここに折り返す数字を入れる { $TempURLText .= $matches[0][$j]; } else { $TempURLText = $TempURLText."<br>".$matches[0][$j]; } } } return "<a href=".$matches[0].">".$TempURLText."</a>"; } $URLFilter ="|http|"; echo preg_replace_callback( $URLFilter , "MakeURLLink", $URL0);

noname#9903
noname#9903
回答No.2

処理は遅くなりますが、 preg_split で一度分解して、 もう一度配列に対して、順に同じ表現で検索して 一致した行で、長さを測り 折り返して置き換えてはどうでしょうか?

  • kotaron
  • ベストアンサー率61% (8/13)
回答No.1

こんにちは、 この問題は、結構悩みますよね。 ワードブレイクがかからない文は、 mb_sTrimWidthなんかで強制的に丸めるとか、 場合により、「リンク」などの文字に置き換えて、 title="長いリンク先"という感じで細くしています。 丸める場合も、title入れておくと良いと思います。 全部に入れると、返って見にくくなりますが・・・ まぁ、ステータスバーを見たら解決するもんだいですが、変なリンク先の場合に困りますので・・・ いろいろと対策を考えて、わたくしも苦労しています。 ご存知かもしれませんが、ワードブレイクがかからないのは、リンクだけではないので、テーブルを乱される対処をする場合は、もう少し対策が必要です。

ntm98
質問者

お礼

回答ありがとうございます。 やっぱりどなたでも悩むんですね、この問題は。 一応解決できまして、#4さんへのお礼欄にコードを記載させていただきました。 ご参考までにどうぞ。

関連するQ&A

  • 正規表現について

    すみませんが、教えてください。 PHP+MYSQLで掲示板のようなサイトを作っています。 投稿したコメントの中にURLがある場合、次の変換で、リンクを設定するようにしています。 $str = ereg_replace("(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)", "<a href=\"\\1\\2\" target=\"_blank\">\\1\\2</a>", $aStr); さらに、次のことがしたいのですが、どうすれば良いのか教えてください。 (1)URLが長い場合、表示する文字列を指定文字数でカットする。 (2)URLのみをリンク設定付で切り出す。 当方、正規表現がほとんど理解できていません。 (オイラリーの本を買ったのですが、時間がなくて学習できていません。) 申し訳ございませんが、こうすれば良いというコードを教えていただければ、幸いです。

    • ベストアンサー
    • PHP
  • preg_replaceでの正規表現について

    お世話になります。 ereg_replace で書いた正規表現による置換処理を、 preg_replace に置き換えようとしています。 (preg_replaceの方が処理が速いとマニュアルにあったので) ところが、preg_replaceでの正規表現検索がうまくいかないで困っています。 基本的には、ereg_replaceの正規表現部分を//で囲んでいるだけです。 具体的には、下記のような処理を書いています。 間違いがあれば、ご指摘いただけましたら幸いです。 //### うまくいっている ereg_replace のパターン ここから ### $html=file_get_contents('template/temple.html'); //ひな形読み込み $search='\{dokuji tag\}.+\{_dokuji tag\}'; $replace=''; $html=ereg_replace($search,$replace,$html); //不要部分の削除 //### うまくいっている ereg_replace のパターン ここまで ### ↓ //### うまくいかない preg_replace のパターン ここから ### $html=file_get_contents('template/temple.html'); //ひな形読み込み $search='/\{dokuji tag\}.+\{_dokuji tag\}/m'; $replace=''; $html=preg_replace($search,$replace,$html); //不要部分の削除 //### うまくいかない preg_replace のパターン ここまで ### //### 置き換えるソース('template/temple.html') ここから ### <!-- {dokuji tag} --> <tr> <td nowrap><strong>タイトル:</strong></td> <td> <input type="text" name="name" size="80" value="{name}" /> </td> </tr> <!-- {_dokuji tag} --> //### 置き換えるソース('template/temple.html') ここまで ### よろしくお願い申し上げます。

    • ベストアンサー
    • PHP
  • PHP5.3以降のereg_replaceについて

    PHP5.3以降にアップデートしたところ、ereg_replaceで書かれている箇所で警告が出るようになりました。 マニュアルを見た限りではpreg_replaceへの移行が推奨されているようなので、preg_replaceに書き換えようと思い、http://melma.com/backnumber_129036_1571788/を参考に、2つ目のパラメータの前後に/を付けましたが、画面に何も表示されず、どのように記述すれば良いか分からなかった為、アドバイスいただける方がいらっしゃいましたら、ご教示の程よろしくお願いします。 なお、ソースは下記となります。 また、記述はhttp://okwave.jp/qa/q849820.html?&status=true&errcode=&msg=&qid=849820を使用させていただいており、やりたいことはURLに自動的にハイパーリンクを付加したいという状況で、ereg_replaceを使用すればできております。 <?php $proto = "私のブログはhttp://www.hoge.com/です。"; $proto = ereg_replace("(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)","<a href=\"\\1\\2\" target=\"_blank\">\\1\\2</a>",$proto); //$proto = preg_replace("(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)","/<a href=\"\\1\\2\" target=\"_blank\">\\1\\2</a>/",$proto); print $proto; ?> 以上、宜しくお願いします。

    • ベストアンサー
    • PHP
  • textarea内のタグを反映させたいのですが

    http://okweb.jp/kotaeru.php3?q=984300を参考に 改行を犠牲にして自動リンクを利用できるようにしたのですが、 HTMLの一部に編集内容を反映したいため FONTタグ等も利用したいんです。 何か良い方法はありませんでしょうか? よろしくお願いします。 <?PHP 文字制限のため省略ですが参考元と同様です。 ?> <html> <title>テキストファイルのデータ更新</title> </head> <body> <form method="post" action="edit.php"> data1の変更 - <textarea name ="data1" rows="5" cols="40"><?php echo preg_replace("/<br>/", "\n", $ini['data1']); ?></textarea><br> data2の変更 - <textarea name ="data2" rows="5" cols="40"><?php echo preg_replace("/<br>/", "\n", $ini['data2']); ?></textarea><br> data3の変更 - <textarea name ="data3" rows="5" cols="40"><?php echo preg_replace("/<br>/", "\n", $ini['data3']); ?></textarea><br> <input type="submit" value="送信"> </form> <table> <tr><td>data1</td><td><?PHP echo ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]", "<a href=\"\\0\">\\0</a>", $ini['data1']); ?></td></tr> <tr><td>data2</td><td><?PHP echo ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]", "<a href=\"\\0\">\\0</a>", $ini['data2']); ?></td></tr> <tr><td>data3</td><td><?PHP echo ereg_replace("[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]", "<a href=\"\\0\">\\0</a>", $ini['data3']); ?></td></tr> </table> </body> </html>

    • 締切済み
    • PHP
  • wiki文法のようにリンク生成

    正規表現について分からない点があり、質問させて頂きます。 いま、 [[link(http://hoge.com?id=123):リンク456]] のように入力された部分を、 <a href="http://hoge.com?id=123">リンク456</a> のように書き換える関数(CreLink())を作っています。 これ自体は作成することができ、機能したのですが、 本文中に記述されたURLをリンクに置き換える関数(EditURL())と競合してしまい、 結果的に正しく機能しないという状況が起きています。 function EditURL($string) { $new_str = mb_ereg_replace("(https?|ftp)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)","<a href=\"\\0\" rel=\"external\">\\0</a>", $string); return $new_str; } 具体的には、CreLink() で生成した href="http://hoge.com?id=123" の部分でも EditURL() が実行されてしまい、 <a href="<a href="http://hoge.com?id=123" rel="external">http://hoge.com?id=123"</a>>リンク456</a> というふうに出力されてしまいます。 文中に入力されたURL部分をリンクに置き換えつつ、 [[link(http://hoge.com?id=123):リンク456]] のように記述されている個所を <a href="http://hoge.com?id=123">リンク456</a> と置き換えるには、どうしたら良いでしょうか?

    • ベストアンサー
    • PHP
  • URLを見つけたら自動でリンク、タイトルを取得する

    よろしくお願い致します。 ------------- 引用元:http://aaa、http://bbb、http://ccc ------------- という文字列がある場合 ------------- 引用元:<a href="http://aaa" target="_blank">タイトルaaa</a>、<a href="http://bbb" target="_blank">タイトルbbb</a>、<a href="http://ccc" target="_blank">タイトルccc</a> ------------- に置き換える方法を考えています。 ------------- <?php // 対象文字列 $text = '引用元:http://aaa、http://bbb、http://ccc'; // パターン $pattern = '/((?:https?|ftp):\/\/[-_.!~*\'()a-zA-Z0-9;\/?:@&=+$,%#]+)/u'; // 置換後の文字列 $replacement = '<a href="\1">\1</a>'; // 置換 $text= preg_replace($pattern,$replacement,$text); // 出力 echo $text; ?> ------------- で ------------- 引用元:<a href="http://aaa" target="_blank">http://aaa</a>、<a href="http://bbb" target="_blank">http://bbb</a>、<a href="http://ccc" target="_blank">http://ccc</a> ------------- までは行けたのですが、タイトルを取得する方法が分かりません。 http://otapps.net/archives/305 こちらを参考に考えたのですが、先に進めずにいます。 分かる方がいらっしゃいましたら、ご教示ください。 よろしくお願い致します。

    • ベストアンサー
    • PHP
  • ereg_replace関数に関して

    教えて下さい。 プログラム上でereg_replace関数を多数使用しています。 この関数は、PHP 5.3.0以上では使えない事がわかり、他の関数に切り替えたいと考えて いますが、書き方がわかりません。 以下の記述をPHP 5.3.0以上で動作させる為には、どのように記述すれば良いでしょうか? 《現在の記述》 $dest=ereg_replace('^', '&gt;' ,$dest); $dest=ereg_replace("\n", "\n>" ,$dest); $dest = ereg_replace("http://[^<>[:space:]]+[[:alnum:]/]", "<a href=\"\\0\">\\0</a>", $src); 初歩的な質問で申し訳ありませんが、教えて下さい。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • mysqlの関数でereg_replace

    レコードから、特定のドメインを含むURLを消去する、といった動作をmysqlの関数で実現しようと考えてます。phpで言うところのereg_replace()のような関数がmysqlであるかどうかということです。 以下のように"bbs"というテーブルの"com"というフィールドからURLに値する文字列を消去するSQL分を実行しましたがこれは動作しませんでした。 update bbs set com = replace(com,regexp '(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)','') where com regexp '(https?|ftp|news)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)'; replace関数の第二引数にregexpを使用することができませんでした。(やり方が間違ってるのでしょうか?) phpのereg_replaceを使用してフィールド"com"に含まれるURLを消去していくというやり方で実現は可能なのですが、動作の軽さやソースのシンプルさを考え、SQL文で実現することを考えてます。 mysqlのヴァージョンは3.23.58です。 よろしくお願いいたします。m(__)m

  • VBで正規表現

    VBで正規表現 下記のような文字列がTextBoxに入力されています。 <a></a>で囲まれた部分の抽出は出来ましたが、 <td></td>タグで囲まれた’18’も取り出したいのですが正規表現ではどの様に記述すれば宜しいでしょうか? 関係有りそうなコードはこれです。 Regex("<a href=""(?<url>.*?)"".*?>(?<text>.*?)</a>" ---------------------------------------- <TR bgcolor=#ffffff> <TD> 18 </TD> <TD><a href="main.py?qtype=userpage&teamnum=162&username=KOTOKO"> KOTOKO </a> </TD> <TD><a href="http://fah-web2.stanford.edu/awards/cert.php?u=KOTOKO&pts=11379753" target="_blank"> 11379753 </a> </TD> <TD><a href="http://fah-web2.stanford.edu/awards/cert.php?u=KOTOKO&pts=16190&t=wus&bg=3" target="_blank"> 16190 </a> </TD> </TR> ----------------------------------------

  • 効率良くURLを拾う正規表現

    掲示板に投稿された文章から、効率良くURL(Email add含む)を拾い、<a>タグを仕込むには、置換処理の中でどのように正規表現を組むのが安全かつ効率的ですか? 例:  私のHPはhttp://www.hoge.com/です。  お問い合わせはhoge@hoge.comまで。         ↓  私のHPは<a href="http://www.hoge.com/">http://www.hoge.com/</a>です。  お問い合わせは<a href="mailto:hoge@hoge.com">hoge@hoge.com</a>まで。

    • ベストアンサー
    • PHP

専門家に質問してみよう