php - PHP:タグ、楕円、リンクアイコンを使用したユーザーリンクの検索、置換、短縮、および美化
6 に答える
HTML Purifierには、すべての頭痛の種から解放される組み込みのリンク化機能があります。
他の機能も、表示する必要があるユーザー入力を処理している場合に見逃すにはあまりにも便利です。
domain.com 形式のリンクを見つけようとするのは骨の折れる作業です。すべての TLD を追跡し、検索でそれらを使用する必要があります。私が入力した最後の文の終わりを入力しなかった場合、この文の先頭はhttp://search.ifへのリンクになります。.in は有効な TLD であり、一般的な単語です。
www.
リンクを開始するかhttp://
、単純な正規表現を記述してそれらをキャプチャしてリンクを追加する必要があることをユーザーに伝えることをお勧めします。
www.google.com
これは URL ではなく、ホスト名です。一般に、任意のテキストで裸のホスト名をマークアップすることはお勧めできません。一般に、任意の単語またはドットで区切られた一連の単語が完全に有効なホスト名であるためです。つまり、先頭のTLD ( www.
「なぜリンクできるのにできwww.stackoverflow.com
ないのstackoverflow.com
?」などの質問を受ける) や末尾の TLD (新しい TLD が導入されるにつれて、ますます非現実的になります。私は ncm.com が好きですが、好きではありませんncm.museum
?」) であり、リンクであってはならないものをマークアップすることがよくあります。
本当に派手な正規表現を書いてみることができます
正規表現なしでどうやってそれを行うのかわかりません。
トリックはマークアップに対処することです。<
入力に,&
および文字を含めることができる場合は"
、それらを HTML 出力に含めてはなりません。入力がプレーンテキストの場合はhtmlspecialchars()
、ニコの回答のようなパターンに単純な置換を適用する前に呼び出すことでそれを行うことができます。
(入力に既にマークアップが含まれている場合は、問題があり、内部にマークアップを追加しないようにするために、どのビットがマークアップであるかを判断する HTML パーサーが必要になる可能性があります。同様に、この後にさらに処理を行う場合は、さらに挿入します。タグの場合、これらの手順は同じ困難を伴う可能性があります.「bbcode」のような言語では、これはしばしばバグやセキュリティの問題につながります.)
別の問題は、末尾の句読点です。リンクの後にピリオド、コンマ、閉じ括弧、感嘆符などを入れるのはよくあることですが、これらはリンクの一部ではないはずですが、実際には有効な文字です。これらを取り除き、リンクに入れないようにすると便利です。しかし、その後、 で終わる Wiki リンクを壊してしまうので、リンクに が含まれていたり、そのようなものがある場合、末尾の文字として)
扱いたくないかもしれません。この種のことは、単純な正規表現の置換では実行できませんが、置換コールバック関数では実行できます。)
(
http://www.exorithm.com/algorithm/view/markup_urlsから
function markup_urls ($text)
{
// split the text into words
$words = preg_split('/([\s\n\r]+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
$text = "";
// iterate through the words
foreach($words as $word) {
// chopword = the portion of the word that will be replaced
$chopword = $word;
$chopword = preg_replace('/^[^A-Za-z0-9]*/', '', $chopword);
if ($chopword <> '') {
// linkword = the text that will replace chopword in the word
$linkword='';
// does it start with http://abc. ?
if (preg_match('/^(http:\/\/)[a-zA-Z0-9_]{2,}.*/', $chopword)) {
$chopword = preg_replace('/[^A-Za-z0-9\/]*$/', '', $chopword);
$linkword = '<a href="'.$chopword.'" target="blank">'.$chopword.'</a>';
// does it equal abc.def.ghi ?
} else if (preg_match('/^[a-zA-Z]{2,}\.([a-zA-Z0-9_]+\.)+[a-zA-Z]{2,}(\/.*)?/', $chopword)) {
$chopword = preg_replace('/[^A-Za-z0-9\/]*$/', '', $chopword);
$linkword = '<a href="http://'.$chopword.'" target="blank">'.$chopword.'</a>';
// does it start with abc@def.ghi ?
} else if (preg_match('/^[a-zA-Z0-9_\.]+\@([a-zA-Z0-9_]{2,}\.)+[a-zA-Z]{2,}.*/', $chopword)) {
$chopword = preg_replace('/[^A-Za-z0-9]*$/', '', $chopword);
$linkword = '<a href="mailto:'.$chopword.'">'.$chopword.'</a>';
}
// replace chopword with linkword in word (if linkword was set)
if ($linkword <> '') {
$word = str_replace($chopword, $linkword, $word);
}
}
// append the word
$text = $text.$word;
}
return $text;
}
機能するはずのそれほど派手な正規表現ではない
/\b(https?:\/\/[^\s+\"\<\>]+)/ig
/\b(www.[^\s+\"\<\>]+)/ig
最後の 2 つは、google.com とこのようなものを区別できないため、正しく行うことができないことに注意してください。ここで、1 つの文を終了し、ピリオドの後にスペースを入れません。
URL の短縮については、URL を$url
:
if (strlen($url) > 20) // Or whatever length you like
{
$shortURL = substr($url, 0, 20)."…";
}
else
{
$shortURL = $url;
}
echo '<a href="'.$url.'" >'.$shortURL.'</a>';
私はここで私が望むようにこれを正確に機能させました:
<?php
$input = <<<EOF
http://www.example.com/
http://example.com
www.example.com
http://iamanextremely.com/long/link/so/I/will/be/trimmed/down/a/bit/so/i/dont/mess
/up/text/wrapping.html
EOF;
function trimlong($match)
{
$url = $match[0];
$display = $url;
if ( strlen($display) > 30 ) {
$display = substr($display,0,30)."...";
}
return '<a href="'.$url.'">'.$display.' <img src="http://static.goalscdn.com/img/external-link.gif" height="10" width="11" /></a>';
}
$output = preg_replace_callback('#(http://|www\\.)[^\\s<]+[^\\s<,.]#i',
array($this,'trimlong'),$input);
echo $output;