ただし、ここに設計があります。たとえば、次のようなリンクを配置します
intextareaどうすればPHPを取得してhttp://
リンクしてから、
print "<a href='http://www.example.com'>http://www.example.com</a>";
私は以前このようなことをしたことを覚えていますが、複雑なリンクで壊れ続けたという馬鹿な証拠ではありませんでした。
別の良いアイデアは、次のようなリンクがある場合です
http://example.com/test.php?val1=bla&val2blablabla%20bla%20bla.bl
修正する
print "<a href='http://example.com/test.php?val1=bla&val2=bla%20bla%20bla.bla'>";
print "http://example.com/test.php";
print "</a>";
これは単なる後の考えです。stackoverflowもおそらくこれを使用できます:D
何か案は
要件を見てみましょう。ハイパーリンクされたURLで表示するユーザー指定のプレーンテキストがあります。
Edit:最新バージョンのチェックアウト Bitbucket 、メールアドレス、認証済みURL、引用符と括弧内のURL、 HTML入力、および更新されたTLDリスト。
Bitbucket issue tracker を使用して、バグと機能強化リクエストを報告してください。彼らはその方法を追跡するのが簡単です(そしてコメント領域を乱雑にしないでください)。
私の見解は次のとおりです。
<?php
$text = <<<EOD
Here are some URLs:
stackoverflow.com/questions/1188129/pregreplace-to-detect-html-php
Here's the answer: http://www.google.com/search?rls=en&q=42&ie=utf-8&oe=utf-8&hl=en. What was the question?
A quick look at http://en.wikipedia.org/wiki/URI_scheme#Generic_syntax is helpful.
There is no place like 127.0.0.1! Except maybe http://news.bbc.co.uk/1/hi/england/surrey/8168892.stm?
Ports: 192.168.0.1:8080, https://example.net:1234/.
Beware of Greeks bringing internationalized top-level domains: xn--hxajbheg2az3al.xn--jxalpdlp.
And remember.Nobody is perfect.
<script>alert('Remember kids: Say no to XSS-attacks! Always HTML escape untrusted input!');</script>
EOD;
$rexProtocol = '(https?://)?';
$rexDomain = '((?:[-a-zA-Z0-9]{1,63}\.)+[-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})';
$rexPort = '(:[0-9]{1,5})?';
$rexPath = '(/[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]*?)?';
$rexQuery = '(\?[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
$rexFragment = '(#[!$-/0-9:;=@_\':;!a-zA-Z\x7f-\xff]+?)?';
// Solution 1:
function callback($match)
{
// Prepend http:// if no protocol specified
$completeUrl = $match[1] ? $match[0] : "http://{$match[0]}";
return '<a href="' . $completeUrl . '">'
. $match[2] . $match[3] . $match[4] . '</a>';
}
print "<pre>";
print preg_replace_callback("&\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))&",
'callback', htmlspecialchars($text));
print "</pre>";
Edit:次のコードは上記の2つの問題を修正しますが、preg_replace_callback
を使用してpreg_match
を多かれ少なかれ再実装しているため、かなり冗長です。
// Solution 2:
$validTlds = array_fill_keys(explode(" ", ".aero .asia .biz .cat .com .coop .edu .gov .info .int .jobs .mil .mobi .museum .name .net .org .pro .tel .travel .ac .ad .ae .af .ag .ai .al .am .an .ao .aq .ar .as .at .au .aw .ax .az .ba .bb .bd .be .bf .bg .bh .bi .bj .bm .bn .bo .br .bs .bt .bv .bw .by .bz .ca .cc .cd .cf .cg .ch .ci .ck .cl .cm .cn .co .cr .cu .cv .cx .cy .cz .de .dj .dk .dm .do .dz .ec .ee .eg .er .es .et .eu .fi .fj .fk .fm .fo .fr .ga .gb .Gd .ge .gf .gg .gh .gi .gl .gm .gn .gp .gq .gr .gs .gt .gu .gw .gy .hk .hm .hn .hr .ht .hu .id .ie .il .im .in .io .iq .ir .is .it .je .jm .jo .jp .ke .kg .kh .ki .km .kn .kp .kr .kw .ky .kz .la .lb .lc .li .lk .lr .ls .lt .lu .lv .ly .ma .mc .md .me .mg .mh .mk .ml .mm .mn .mo .mp .mq .mr .ms .mt .mu .mv .mw .mx .my .mz .na .nc .ne .nf .ng .ni .nl .no .np .nr .nu .nz .om .pa .pe .pf .pg .ph .pk .pl .pm .pn .pr .ps .pt .pw .py .qa .re .ro .rs .ru .rw .sa .sb .sc .sd .se .sg .sh .si .sj .sk .sl .sm .sn .so .sr .st .su .sv .sy .sz .tc .td .tf .tg .th .tj .tk .tl .tm .tn .to .tp .tr .tt .tv .tw .tz .ua .ug .uk .us .uy .uz .va .vc .ve .vg .vi .vn .vu .wf .ws .ye .yt .yu .za .zm .zw .xn--0zwm56d .xn--11b5bs3a9aj6g .xn--80akhbyknj4f .xn--9t4b11yi5a .xn--deba0ad .xn--g6w251d .xn--hgbk6aj7f53bba .xn--hlcj6aya9esc7a .xn--jxalpdlp .xn--kgbechtv .xn--zckzah .arpa"), true);
$position = 0;
while (preg_match("{\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))}", $text, &$match, PREG_OFFSET_CAPTURE, $position))
{
list($url, $urlPosition) = $match[0];
// Print the text leading up to the URL.
print(htmlspecialchars(substr($text, $position, $urlPosition - $position)));
$domain = $match[2][0];
$port = $match[3][0];
$path = $match[4][0];
// Check if the TLD is valid - or that $domain is an IP address.
$tld = strtolower(strrchr($domain, '.'));
if (preg_match('{\.[0-9]{1,3}}', $tld) || isset($validTlds[$tld]))
{
// Prepend http:// if no protocol specified
$completeUrl = $match[1][0] ? $url : "http://$url";
// Print the hyperlink.
printf('<a href="%s">%s</a>', htmlspecialchars($completeUrl), htmlspecialchars("$domain$port$path"));
}
else
{
// Not a valid URL.
print(htmlspecialchars($url));
}
// Continue text parsing from after the URL.
$position = $urlPosition + strlen($url);
}
// Print the remainder of the text.
print(htmlspecialchars(substr($text, $position)));
ここに私が見つけたものがあります
function make_links_blank($text)
{
return preg_replace(
array(
'/(?(?=<a[^>]*>.+<\/a>)
(?:<a[^>]*>.+<\/a>)
|
([^="\']?)((?:https?|ftp|bf2|):\/\/[^<> \n\r]+)
)/iex',
'/<a([^>]*)target="?[^"\']+"?/i',
'/<a([^>]+)>/i',
'/(^|\s)(www.[^<> \n\r]+)/iex',
'/(([_A-Za-z0-9-]+)(\\.[_A-Za-z0-9-]+)*@([A-Za-z0-9-]+)
(\\.[A-Za-z0-9-]+)*)/iex'
),
array(
"stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\">\\2</a>\\3':'\\0'))",
'<a\\1',
'<a\\1 target="_blank">',
"stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\">\\2</a>\\3':'\\0'))",
"stripslashes((strlen('\\2')>0?'<a href=\"mailto:\\0\">\\0</a>':'\\0'))"
),
$text
);
}
わたしにはできる。そして、それは電子メールとURLのために機能します、私自身の質問に答えて申し訳ありません。 :(
しかし、これは唯一の作品です
ここに私が見つけたリンクがあります: http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_21878567.html
専門家の交換であるため、事前に試してください。
皆さんは、状況に適した複雑で複雑なものを進める方法を話しているのですが、ほとんどの場合、単純な不注意な解決策が必要です。これはどうですか?
preg_replace('/(http[s]{0,1}\:\/\/\S{4,})\s{0,}/ims', '<a href="$1" target="_blank">$1</a> ', $text_msg);
試してみて、それが満たさないクレイジーなURLを教えてください。
関数で正規表現を使用したコード
<?php
//Function definations
function MakeUrls($str)
{
$find=array('`((?:https?|ftp)://\S+[[:alnum:]]/?)`si','`((?<!//)(www\.\S+[[:alnum:]]/?))`si');
$replace=array('<a href="$1" target="_blank">$1</a>', '<a href="http://$1" target="_blank">$1</a>');
return preg_replace($find,$replace,$str);
}
//Function testing
$str="www.cloudlibz.com";
$str=MakeUrls($str);
echo $str;
?>
私はこの機能を使用していますが、それは私のために機能します
function AutoLinkUrls($str,$popup = FALSE){
if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches)){
$pop = ($popup == TRUE) ? " target=\"_blank\" " : "";
for ($i = 0; $i < count($matches['0']); $i++){
$period = '';
if (preg_match("|\.$|", $matches['6'][$i])){
$period = '.';
$matches['6'][$i] = substr($matches['6'][$i], 0, -1);
}
$str = str_replace($matches['0'][$i],
$matches['1'][$i].'<a href="http'.
$matches['4'][$i].'://'.
$matches['5'][$i].
$matches['6'][$i].'"'.$pop.'>http'.
$matches['4'][$i].'://'.
$matches['5'][$i].
$matches['6'][$i].'</a>'.
$period, $str);
}//end for
}//end if
return $str;
}//end AutoLinkUrls
すべてのクレジットは- http://snipplr.com/view/68586/
楽しい!
この正規表現は、これらの新しい3文字以上のトップレベルドメインを除くすべてのリンクと一致する必要があります...
{ \\ b #先頭部分に一致(proto:// hostname、または単にホスト名) ( #http://、またはhttps: //先頭部分 (https?):// [-\\ w] +(\\。\\ w [-\\ w] *)+ | #または、より具体的な部分式 でホスト名を見つけようとします(?i:[a-z0-9](?:[-a-z0-9] * [a-z0-9]) ?\\。)+#サブドメイン #.comなどで終了します。これらの場合、小文字が必要です (?-i:com \\ b | edu \\ b | biz \\ b | gov \\ b | in(?:t | fo)\\ b#.intまたは.info | mil \\ b | net \\ b | org \\ b | [az] [az] \\。[az] [az] \\ b#two -文字の国コード ) ) #オプションのポート番号を許可 (:\\ d +)? #URLの残りの部分はオプションで、/ ( / で始まります。#残りはうまくいくように思われるものの発見的手法です。 [^。!、?; "\\ '()\ [\]\{\}\s\x7F-\\ xFF] * ( [。!、?] + [^。!、?; "\\ '()\\ [\\]\{\\}\s \\ x7F-\\ xFF] + )* )? } ix
それは私によって書かれたものではありません、私はそれをどこから手に入れたかはよくわかりません。
これにより、電子メールアドレスが取得されます。
$string = "bah bah [email protected] foo";
$match = preg_match('/[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)*\@[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+(?:\.[^\x00-\x20()<>@,;:\\".[\]\x7f-\xff]+)+/', $string, $array);
print_r($array);
// outputs:
Array
(
[0] => [email protected]
)
Php 7を実行しているVPSの上のコメントの1つで述べたように、警告を発し始めました警告:preg_replace():/ e修飾子はサポートされなくなりました。代わりにpreg_replace_callbackを使用してください。置換後のバッファは空/偽でした。
コードを書き直し、いくつかの改善を行いました。あなたが著者セクションにいるべきだと思うなら、関数make_links_blank名の上にあるコメントを自由に編集してください。出力に空白が挿入されないように、意図的に終了phpを使用していません。
<?php
class App_Updater_String_Util {
public static function get_default_link_attribs( $regex_matches = [] ) {
$t = ' target="_blank" ';
return $t;
}
/**
* App_Updater_String_Util::set_protocol();
* @param string $link
* @return string
*/
public static function set_protocol( $link ) {
if ( ! preg_match( '#^https?#si', $link ) ) {
$link = 'http://' . $link;
}
return $link;
}
/**
* Goes through text and makes whatever text that look like a link an html link
* which opens in a new tab/window (by adding target attribute).
*
* Usage: App_Updater_String_Util::make_links_blank( $text );
*
* @param str $text
* @return str
* @see http://stackoverflow.com/questions/1188129/replace-urls-in-text-with-html-links
* @author Angel.King.47 | http://dashee.co.uk
* @author Svetoslav Marinov (Slavi) | http://orbisius.com
*/
public static function make_links_blank( $text ) {
$patterns = [
'#(?(?=<a[^>]*>.+?<\/a>)
(?:<a[^>]*>.+<\/a>)
|
([^="\']?)((?:https?|ftp):\/\/[^<> \n\r]+)
)#six' => function ( $matches ) {
$r1 = empty( $matches[1] ) ? '' : $matches[1];
$r2 = empty( $matches[2] ) ? '' : $matches[2];
$r3 = empty( $matches[3] ) ? '' : $matches[3];
$r2 = empty( $r2 ) ? '' : App_Updater_String_Util::set_protocol( $r2 );
$res = ! empty( $r2 ) ? "$r1<a href=\"$r2\">$r2</a>$r3" : $matches[0];
$res = stripslashes( $res );
return $res;
},
'#(^|\s)((?:https?://|www\.|https?://www\.)[^<>\ \n\r]+)#six' => function ( $matches ) {
$r1 = empty( $matches[1] ) ? '' : $matches[1];
$r2 = empty( $matches[2] ) ? '' : $matches[2];
$r3 = empty( $matches[3] ) ? '' : $matches[3];
$r2 = ! empty( $r2 ) ? App_Updater_String_Util::set_protocol( $r2 ) : '';
$res = ! empty( $r2 ) ? "$r1<a href=\"$r2\">$r2</a>$r3" : $matches[0];
$res = stripslashes( $res );
return $res;
},
// Remove any target attribs (if any)
'#<a([^>]*)target="?[^"\']+"?#si' => '<a\\1',
// Put the target attrib
'#<a([^>]+)>#si' => '<a\\1 target="_blank">',
// Make emails clickable Mailto links
'/(([\w\-]+)(\\.[\w\-]+)*@([\w\-]+)
(\\.[\w\-]+)*)/six' => function ( $matches ) {
$r = $matches[0];
$res = ! empty( $r ) ? "<a href=\"mailto:$r\">$r</a>" : $r;
$res = stripslashes( $res );
return $res;
},
];
foreach ( $patterns as $regex => $callback_or_replace ) {
if ( is_callable( $callback_or_replace ) ) {
$text = preg_replace_callback( $regex, $callback_or_replace, $text );
} else {
$text = preg_replace( $regex, $callback_or_replace, $text );
}
}
return $text;
}
}
私はこの答えが受け入れられ、この質問はかなり古いことを知っていますが、他の実装を探している他の人にとっては有用です。
これは、2009年7月27日にAngel.King.47によって投稿されたコードの修正版です。
$text = preg_replace(
array(
'/(^|\s|>)(www.[^<> \n\r]+)/iex',
'/(^|\s|>)([_A-Za-z0-9-]+(\\.[A-Za-z]{2,3})?\\.[A-Za-z]{2,4}\\/[^<> \n\r]+)/iex',
'/(?(?=<a[^>]*>.+<\/a>)(?:<a[^>]*>.+<\/a>)|([^="\']?)((?:https?):\/\/([^<> \n\r]+)))/iex'
),
array(
"stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a> \\3':'\\0'))",
"stripslashes((strlen('\\2')>0?'\\1<a href=\"http://\\2\" target=\"_blank\">\\2</a> \\4':'\\0'))",
"stripslashes((strlen('\\2')>0?'\\1<a href=\"\\2\" target=\"_blank\">\\3</a> ':'\\0'))",
),
$text
);
変更点:
「SørenLøvborg」が述べているように、この関数はURLをエスケープしません。私は彼/彼女のクラスを試してみましたが、期待通りに機能しませんでした(ユーザーを信頼していない場合は、まず彼/彼女のコードを試してください)。
の線に沿って何か:
<?php
if(preg_match('@^http://(.*)\s|$@g', $textarea_url, $matches)) {
echo '<a href=http://", $matches[1], '">', $matches[1], '</a>';
}
?>
IANAを信頼したい場合、そこで使用されている公式にサポートされているTLDの現在のリストを取得できます。
$validTLDs =
explode("\n", file_get_contents('http://data.iana.org/TLD/tlds-alpha-by-domain.txt')); //get the official list of valid tlds
array_shift($validTLDs); //throw away first line containing meta data
array_pop($validTLDs); //throw away last element which is empty
SørenLøvborgのソリューション#2をもう少し冗長にし、リストを更新する手間を省きます。最近では新しいtldが不注意に捨てられています;)
これは私のために働いた(答えの1つをPHP関数)に変えた)
function make_urls_from_text ($text){
return preg_replace('/(http[s]{0,1}\:\/\/\S{4,})\s{0,}/ims', '<a href="$1" target="_blank">$1 </a>', $text);
}
このclass
はURLをテキストに変更し、ホームのURLをそのまま維持します。これがあなたの時間を節約するのに役立つことを願っています。お楽しみください。
class RegClass
{
function preg_callback_url($matches)
{
//var_dump($matches);
//Get the matched URL text <a>text</a>
$text = $matches[2];
//Get the matched URL link <a href ="http://www.test.com">text</a>
$url = $matches[1];
if($url=='href ="http://www.test.com"'){
//replace all a tag as it is
return '<a href='.$url.' rel="nofollow"> '.$text.' </a>';
}else{
//replace all a tag to text
return " $text " ;
}
}
function ParseText($text){
$text = preg_replace( "/www\./", "http://www.", $text );
$regex ="/http:\/\/http:\/\/www\./"
$text = preg_replace( $regex, "http://www.", $text );
$regex2 = "/https:\/\/http:\/\/www\./";
$text = preg_replace( $regex2, "https://www.", $text );
return preg_replace_callback('/<a\s(.+?)>(.+?)<\/a>/is',
array( &$this, 'preg_callback_url'), $text);
}
}
$regexp = new RegClass();
echo $regexp->ParseText($text);