没有http,https或www的PHP preg_replace URL

时间:2014-04-19 20:47:35

标签: php arrays preg-replace tld

我对正则表达式和东西不太好。我知道如何将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

2 个答案:

答案 0 :(得分:1)

我只是浏览了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为其定义测试数据数组 - 它会让您确信您的解决方案是合理的。

答案 1 :(得分:0)

$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