PHP Linkify内容链接 [英] PHP Linkify Links In Content

查看:58
本文介绍了PHP Linkify内容链接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在做一个小项目,我发现自己处在一个需要php函数的位置,该函数可以链接数据中的URL,同时使我可以在一些我不想链接的链接上设置例外.对如何执行此操作有任何想法吗?

I've been working on a little project, and I find myself in a position where I need a php function which can linkify URLs in my data, while enabling me to set some exceptions on links I don't want to linkify. Any idea of how to do this?

推荐答案

我在GitHub上有一个开源项目: LinkifyURL 您可能要考虑.它具有一个功能:linkify(),可从文本中提取URL并将其转换为链接.请注意,这不是一件容易的事,要正确完成! (请参阅: URL问题-和请务必阅读注释的主题,以掌握所有可能出错的地方.)

I have an open source project on GitHub: LinkifyURL which you may want to consider. It has a function: linkify() which plucks URLs from text and converts them to links. Note that this is not a trivial task to do correctly! (See: The Problem With URLs - ands be sure to read the thread of comments to grasp all the things that can go wrong.)

如果您确实不需要链接特定域(即vimeo和youtube),则可以使用修改后的PHP函数linkify_filtered(以有效的测试脚本形式)来满足您的需求:

If you really need to NOT linkify specific domains (i.e. vimeo and youtube), here is a modified PHP function linkify_filtered (in the form of a working test script) that does what you need:

<?php // test.php 20110313_1200

function linkify_filtered($text) {
    $url_pattern = '/# Rev:20100913_0900 github.com\/jmrware\/LinkifyURL
    # Match http & ftp URL that is not already linkified.
      # Alternative 1: URL delimited by (parentheses).
      (\()                     # $1  "(" start delimiter.
      ((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&\'()*+,;=:\/?#[\]@%]+)  # $2: URL.
      (\))                     # $3: ")" end delimiter.
    | # Alternative 2: URL delimited by [square brackets].
      (\[)                     # $4: "[" start delimiter.
      ((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&\'()*+,;=:\/?#[\]@%]+)  # $5: URL.
      (\])                     # $6: "]" end delimiter.
    | # Alternative 3: URL delimited by {curly braces}.
      (\{)                     # $7: "{" start delimiter.
      ((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&\'()*+,;=:\/?#[\]@%]+)  # $8: URL.
      (\})                     # $9: "}" end delimiter.
    | # Alternative 4: URL delimited by <angle brackets>.
      (<|&(?:lt|\#60|\#x3c);)  # $10: "<" start delimiter (or HTML entity).
      ((?:ht|f)tps?:\/\/[a-z0-9\-._~!$&\'()*+,;=:\/?#[\]@%]+)  # $11: URL.
      (>|&(?:gt|\#62|\#x3e);)  # $12: ">" end delimiter (or HTML entity).
    | # Alternative 5: URL not delimited by (), [], {} or <>.
      (                        # $13: Prefix proving URL not already linked.
        (?: ^                  # Can be a beginning of line or string, or
        | [^=\s\'"\]]          # a non-"=", non-quote, non-"]", followed by
        ) \s*[\'"]?            # optional whitespace and optional quote;
      | [^=\s]\s+              # or... a non-equals sign followed by whitespace.
      )                        # End $13. Non-prelinkified-proof prefix.
      ( \b                     # $14: Other non-delimited URL.
        (?:ht|f)tps?:\/\/      # Required literal http, https, ftp or ftps prefix.
        [a-z0-9\-._~!$\'()*+,;=:\/?#[\]@%]+ # All URI chars except "&" (normal*).
        (?:                    # Either on a "&" or at the end of URI.
          (?!                  # Allow a "&" char only if not start of an...
            &(?:gt|\#0*62|\#x0*3e);                  # HTML ">" entity, or
          | &(?:amp|apos|quot|\#0*3[49]|\#x0*2[27]); # a [&\'"] entity if
            [.!&\',:?;]?        # followed by optional punctuation then
            (?:[^a-z0-9\-._~!$&\'()*+,;=:\/?#[\]@%]|$)  # a non-URI char or EOS.
          ) &                  # If neg-assertion true, match "&" (special).
          [a-z0-9\-._~!$\'()*+,;=:\/?#[\]@%]* # More non-& URI chars (normal*).
        )*                     # Unroll-the-loop (special normal*)*.
        [a-z0-9\-_~$()*+=\/#[\]@%]  # Last char can\'t be [.!&\',;:?]
      )                        # End $14. Other non-delimited URL.
    /imx';
//    $url_replace = '$1$4$7$10$13<a href="$2$5$8$11$14">$2$5$8$11$14</a>$3$6$9$12';
//    return preg_replace($url_pattern, $url_replace, $text);
    $url_replace = '_linkify_filter_callback';
    return preg_replace_callback($url_pattern, $url_replace, $text);
}
function _linkify_filter_callback($m)
{ // Filter out youtube and vimeo domains.
    $pre  = $m[1].$m[4].$m[7].$m[10].$m[13];
    $url  = $m[2].$m[5].$m[8].$m[11].$m[14];
    $post = $m[3].$m[6].$m[9].$m[12];
    if (preg_match('/\b(?:youtube|vimeo)\.com\b/', $url)) {
        return $pre . $url . $post;
    } // else linkify...
    return $pre .'<a href="'. $url .'">' . $url .'</a>' .$post;
}

// Create some test data.
$data = 'Plain URLs (not delimited):
foo http://example.com bar...
foo http://example.com:80 bar...
foo http://example.com:80/path/ bar...
foo http://example.com:80/path/file.txt bar...
foo http://example.com:80/path/file.txt?query=val&var2=val2 bar...
foo http://example.com:80/path/file.txt?query=val&var2=val2#fragment bar...
foo http://example.com/(file\'s_name.txt) bar... (with \' and (parentheses))
foo http://[2001:0db8:85a3:08d3:1319:8a2e:0370:7348] bar... ([IPv6 literal])
foo http://[2001:0db8:85a3:08d3:1319:8a2e:0370:7348]/file.txt bar... ([IPv6] with path)
foo http://youtube.com bar...
foo http://youtube.com:80 bar...
foo http://youtube.com:80/path/ bar...
foo http://youtube.com:80/path/file.txt bar...
foo http://youtube.com:80/path/file.txt?query=val&var2=val2 bar...
foo http://youtube.com:80/path/file.txt?query=val&var2=val2#fragment bar...
foo http://youtube.com/(file\'s_name.txt) bar... (with \' and (parentheses))
foo http://vimeo.com bar...
foo http://vimeo.com:80 bar...
foo http://vimeo.com:80/path/ bar...
foo http://vimeo.com:80/path/file.txt bar...
foo http://vimeo.com:80/path/file.txt?query=val&var2=val2 bar...
foo http://vimeo.com:80/path/file.txt?query=val&var2=val2#fragment bar...
foo http://vimeo.com/(file\'s_name.txt) bar... (with \' and (parentheses))
';
// Verify it works...
echo(linkify_filtered($data) ."\n");

?>

这使用回调函数进行过滤.是的,正则表达式很复杂(但是事实证明是个问题!).您可以在此处查看linkify()的交互式Javascript版本,该版本正在起作用: URL链接化(HTTP/FTP ).

This employs a callback function to do the filtering. Yes, the regex is complex (but so it the problem as it turns out!). You can see the interactive Javascript version of linkify() in action here: URL Linkification (HTTP/FTP).

此外,John Gruber有一个很好的正则表达式来进行链接化.请参阅:用于匹配URL的改进的自由,准确的正则表达式模式.但是,他的正则表达式在某些情况下会遭受灾难性的回溯. (我已经写信给他,但是他还没有回应.)

Also, John Gruber has a pretty good regex to do linkification. See: An Improved Liberal, Accurate Regex Pattern for Matching URLs. However, his regex suffers catastrophic backtracking under certain circumstances. (I've written to him about this, but he has yet to respond.)

希望这会有所帮助! :)

Hope this helps! :)

这篇关于PHP Linkify内容链接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆