Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- function escape_and_linkify($text) {
- $regex =
- '`https?+:(?://(?:(?:[-.0-9_a-z~]|%[0-9a-f][0-9a-f]' .
- '|[!$&-,:;=])*+@)?+(?:\[(?:(?:[0-9a-f]{1,4}:){6}(?:' .
- '[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d{2}|2' .
- '[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25' .
- '[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?' .
- ':\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|::(?:[0-9a-f' .
- ']{1,4}:){5}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1' .
- '-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{' .
- '2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\\' .
- 'd|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])' .
- ')|(?:[0-9a-f]{1,4})?+::(?:[0-9a-f]{1,4}:){4}(?:[0-' .
- '9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d{2}|2[0-' .
- '4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-' .
- '5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d' .
- '|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:[0-9a-f]{' .
- '1,4}:)?+[0-9a-f]{1,4})?+::(?:[0-9a-f]{1,4}:){3}(?:' .
- '[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d{2}|2' .
- '[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25' .
- '[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?' .
- ':\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:[0-9a-' .
- 'f]{1,4}:){0,2}[0-9a-f]{1,4})?+::(?:[0-9a-f]{1,4}:)' .
- '{2}(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\\' .
- 'd{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4' .
- ']\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5' .
- '])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:' .
- '[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?+::[0-9a-f]{1,4' .
- '}:(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d' .
- '{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]' .
- '\d|25[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]' .
- ')\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:[' .
- '0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?+::(?:[0-9a-f]{1' .
- ',4}:[0-9a-f]{1,4}|(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25' .
- '[0-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?' .
- ':\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\\' .
- 'd|1\d{2}|2[0-4]\d|25[0-5]))|(?:(?:[0-9a-f]{1,4}:){' .
- '0,5}[0-9a-f]{1,4})?+::[0-9a-f]{1,4}|(?:(?:[0-9a-f]' .
- '{1,4}:){0,6}[0-9a-f]{1,4})?+::|v[0-9a-f]++\.[!$&-.' .
- '0-;=_a-z~]++)\]|(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0' .
- '-5])\.(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\\' .
- 'd|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.(?:\d|[1-9]\d|' .
- '1\d{2}|2[0-4]\d|25[0-5])|(?:[-.0-9_a-z~]|%[0-9a-f]' .
- '[0-9a-f]|[!$&-,;=])*+)(?::\d*+)?+(?:/(?:[-.0-9_a-z' .
- '~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*+)*+|/(?:(?:[-.0' .
- '-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])++(?:/(?:[-' .
- '.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*+)*+)?+|' .
- '(?:[-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])++(?' .
- ':/(?:[-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&-,:;=@])*+' .
- ')*+)?+(?:\?+(?:[-.0-9_a-z~]|%[0-9a-f][0-9a-f]|[!$&' .
- '-,/:;=?+@])*+)?+(?:#(?:[-.0-9_a-z~]|%[0-9a-f][0-9a' .
- '-f]|[!$&-,/:;=?+@])*+)?+`i'
- ;
- $i = 2;
- return preg_replace_callback(
- $regex,
- function ($m) use (&$i) {
- $p = parse_url(htmlspecialchars_decode($m[0], ENT_QUOTES));
- if (!isset($p['host'])) {
- return false;
- }
- $p += array_fill_keys(array('path', 'query'), '');
- parse_str($p['query'], $q);
- switch ($p['host']) {
- case 'www.nicovideo.jp':
- return
- preg_match('@^/watch/([sn]m\d++)/*+$@', $p['path'], $n) && ($i-- > 0) ?
- '<script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/' . $n[1] . '"></script>' :
- htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8')
- ;
- case 'nico.ms':
- return
- preg_match('@^/([sn]m\d++)/*+$@', $p['path'], $n) && ($i-- > 0) ?
- '<script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/' . $n[1] . '"></script>' :
- htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8')
- ;
- case 'youtu.be':
- return
- preg_match('@^/(\w++)/*+$@', $p['path'], $n) && ($i-- > 0) ?
- '<iframe width="420" height="315" src="//www.youtube.com/embed/' . $n[1] .'" frameborder="0" allowfullscreen></iframe>' :
- htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8')
- ;
- case 'www.youtube.com':
- case 'youtube.com':
- case 'jp.youtube.com':
- if (!isset($q['v']) || !is_string($q['v'])) {
- return false;
- }
- return
- preg_match('@^/(\w++)/*+$@', $p['path'], $n) && ($i-- > 0) ?
- '<iframe width="420" height="315" src="//www.youtube.com/embed/' . $q['v'] .'" frameborder="0" allowfullscreen></iframe>' :
- htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8')
- ;
- default:
- return htmlspecialchars($m[0], ENT_QUOTES, 'UTF-8');
- }
- },
- htmlspecialchars($text, ENT_QUOTES, 'UTF-8')
- );
- }
- $text = <<<EOD
- Youtubeにはhttp://www.youtube.com/watch?v=s0SE8GMgeEIとか
- http://youtu.be/s0SE8GMgeEIのようなURLフォーマットがあります。
- http://www.youtube.com/watch?foo=hoge&v=s0SE8GMgeEI&bar=hogeのように
- 余分なクエリがついていてもちゃんと処理すべきでしょう。
- 日本に限定するならば
- http://jp.youtube.com/watch?v=s0SE8GMgeEIもちゃんと処理すべきですね。
- 一方ニコニコ動画には
- http://www.nicovideo.jp/watch/sm1136355だけではなく
- http://www.nicovideo.jp/watch/nm1136355のように、
- 「s」と「m」両方が来る可能性があります。また、
- http://nico.ms/sm1136355のような短縮URLもあります。
- これらにはちゃんと対応すべきです。
- とはいっても、無効なURLもちゃんと判別しなければなりません。
- 例えばhttp://youtu.be/s0SE8GMgeEI/hogehoge&a=bとかは明らかにおかしいし、
- http://www.nicovideo.jp/watch/nm11363abcもニコニコ動画の仕様としてはおかしいです。
- こういったものは無視する必要があります。当然、関係ないものはエスケープして表示させましょう。
- 「&」「<」「>」といった文字がちゃんとエスケープされるか確認してください。
- EOD;
- echo escape_and_linkify($text);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement