【问题标题】:PHP preg_replace URL without http, https or wwwPHP preg_replace URL 没有 http、https 或 www
【发布时间】:2014-06-04 05:10:32
【问题描述】:

我不太擅长正则表达式之类的东西。我知道如何将http://google.com 和 www.google.com 更改为链接。但是,我希望我的脚本围绕以下字符串获取链接:

Hello. Have you visited [link goes here]google.com[/link goes here] today?
Hello. Have you visited [link goes here]www.google.com[/link goes here] today?
Hello. Have you visited [link goes here]http://google.com[/link goes here] today?
Hello. Have you visited [link goes here]https://google.com[/link goes here] today?

当然,我真的希望表达式允许尽可能多的字符。但是对于第一个链接起作用,我只能想到一个解释(我不希望人们开始写text.text,它会变成一个链接):

<?php
$tlds = array("com", "net", "org", "info", "no", "dk", "se");
foreach($tlds as $tld){
$string = preg_replace("something", "something", $string);
}
?>

你们中有人知道该怎么做吗? :P

我希望它类似于 Autolinker.js,仅在 PHP 中:https://github.com/gregjacobs/Autolinker.js

【问题讨论】:

  • 在告诉我使用 google 之前:阅读我的要求。我希望 google.com 变成超链接,即使 http://、https:// 或 www 也是如此。未输入。我知道如何编写代码来与协议建立链接,但是,我也想将没有协议的链接变成链接。

标签: php arrays preg-replace tld


【解决方案1】:
$template = <<< EOF
Hello. Have you visited google.com today?
Hello. Have you visited www.google.com today?
Hello. Have you visited http://google.com today?
Hello. Have you visited https://google.com today?
EOF;

$template = preg_replace_callback('/(?=(([\w\/\/:.]+)\.(?:com|net|org|info|no|dk|se)))\b(?:(?:https?|ftp|file):\/\/|(?:www\.|ftp\.)?)
      (?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#\/%=~_|$?!:,.])*
      (?:\([-A-Z0-9+&@#\/%=~_|$?!:,.]*\)|[A-Z0-9+&@#\/%=~_|$])/ix','my_callback',$template);

function my_callback($matches) {

 //check it the link has the protocol if not adds it.
if (preg_match('/https?/ix', $matches[1])) {
    $link = $matches[1];
    return "<a href=\"$link\">$link</a>";
} else {
    $link = $matches[1];
    return "<a href=\"http://$link\">http://$link</a>";
}
}

echo $template;

http://ideone.com/D1E5EK

【讨论】:

    【解决方案2】:

    我刚刚浏览了previous questions 以获得一个半正则表达式来匹配域并稍微调整了它 - 如果你继续寻找可能会有更好的。

    <?php
    
    $test = 'Hello. Have you visited google.com today?
    Hello. Have you visited www.google.com today?
    Hello. Have you visited http://google.com today?
    Hello. Have you visited https://google.com today?';
    
    $func = function ($match) {
    
        $text   = trim($match[0]);
        $pieces = parse_url($text);
        $scheme = array_key_exists('scheme', $pieces) ? $pieces['scheme'] : 'http';
        $host   = isset($pieces['host']) ? $pieces['host'] : $pieces['path'];
        $link   = sprintf('%s://%s', $scheme, $host);
    
        return sprintf('<a href="%s">%s</a>', $link, $text);
    };
    
    echo preg_replace_callback('/((http[s]?:\/\/)?(?>[a-z\-0-9]{2,}\.){1,}[a-z]{2,8})(?:\s|\/)/m', $func, $test);
    

    我的输出如下:

    Hello. Have you visited <a href="http://google.com">google.com</a>today?
    Hello. Have you visited <a href="http://www.google.com">www.google.com</a>today?
    Hello. Have you visited <a href="http://google.com">http://google.com</a>today?
    Hello. Have you visited <a href="https://google.com">https://google.com</a>today?
    

    我希望这就是你所追求的。

    (我不希望人们开始写text.text,它会变成一个链接)

    同意,那会很烦人 :-) - 一旦你确定了你的解决方案,你可能应该对这个方法进行单元测试。使用 PHPUnit 编写测试,并使用 data provider 为其定义一组测试数据 - 它会让您确信您的解决方案是合理的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 2015-04-06
      • 1970-01-01
      • 2014-07-27
      • 2014-12-16
      • 1970-01-01
      • 2014-05-07
      相关资源
      最近更新 更多