【问题标题】:Auto-link regular expression自动链接正则表达式
【发布时间】:2012-06-08 03:16:33
【问题描述】:

我正在使用 PHP 函数自动将文本字符串中的 URL 转换为人们可以点击的实际链接。它似乎在大多数情况下都有效,但我发现有些情况下它不起作用。

我根本不懂正则表达式,所以我希望有人能帮我解决这个问题。

这是我目前使用的模式:

$pattern = "/(((http[s]?:\/\/)|(www\.))(([a-z][-a-z0-9]+\.)?[a-z][-a-z0-9]+\.[a-z]+(\.[a-z]{2,2})?)\/?[a-z0-9.,_\/~#&=;%+?-]+[a-z0-9\/#=?]{1,1})/is";

但是这里有一些我发现这个模式不匹配的链接:

  • www.oakvilletransit.ca - 不确定,但假设它不匹配,因为国家/地区代码由两个字母组成
  • www.grt.ca - 另一个无法使用 .ca 域的网站
  • 其他几个 .ca 地址
  • freepublictransports.com - 没有 www 的地址。或 http:// 在他们面前。我希望这些也能正常工作。
  • www.222tips.com - 假设由于地址开头的数字不匹配。

有谁知道我可以如何修改该正则表达式模式以匹配这些情况?

EDIT - 它还应该匹配结尾可能有句点的 URL。如果 URL 是句子的最后一部分,则末尾可能有一个句点,不应包含在实际链接中。目前,这种模式也考虑到了这一点。

EDIT 2 - 我正在使用这样的模式:

$pattern = "/((http|https):\/\/)?([a-z0-9-]+\.)?[a-z][a-z0-9-]+(\.[a-z]{2,6}){1,3}(\/[a-z0-9.,_\/~#&=;%+?-]*)?/is";
  $string = preg_replace($pattern, " <a target='_blank' href='$1'>$1</a>", $string);
  // fix URLs without protocols
  $string = preg_replace("/href='www/", "href='http://www", $string);
  return $string;

【问题讨论】:

  • 正则表达式提示:[s]? 不是必需的。只需使用s?
  • 正则表达式提示:{1,1} 没有任何意义。 {2,2} 也没有。
  • 好的,我在另一个 SO 问题上找到了这段代码。所以改变[s]?到s?并且删除 {1,1} 和 {2,2} 应该没有区别吗?
  • 不,没有区别。但请确保将{2,2} 替换为{2};不要只是把它拿出来。
  • Regular Expression for URL 的可能重复项

标签: php regex url


【解决方案1】:

以下正则表达式将匹配 URL:

  • (可选)使用http://https://
  • (可选)带有子域(www.example.comhelp.example.com 等)
  • 具有 1-3 个域扩展名,每个扩展名必须为 2-6 个字符(www.example.com.guwww.example.com.au.museum 等)
  • (可选)末尾带有正斜杠
  • (可选)正斜杠后有有效字符

末尾的/i 使其不区分大小写

/((http|https):\/\/)?([a-z0-9-]+\.)?[a-z0-9-]+(\.[a-z]{2,6}){1,3}(\/[a-z0-9.,_\/~#&amp;=;%+?-]*)?/is

编辑:这将不匹配任何末尾的“挂起”句点(例如句子的结尾),因为它不是 URL 的一部分,也不应该包含在 @ 987654329@ 链接的属性。

编辑 2: 在您的第一个 preg_replace() 中,将 $1 更改为 $0。这将插入整个匹配的字符串而不是它的单个部分。

编辑 3:更新 2)这是一种更好的方法,您可以在开头检查 http://https://

preg_replace("/href='[^h][^t][^t][^p][^s]?[^:]/", "/href='http:\/\/", $string);

【讨论】:

  • 德普。在 regexbuddy 上做了这个,忘了逃避那两个。更新答案,谢谢。 编辑:我从来不知道你可以使用不同的字符作为分隔符!很高兴知道这一点,谢谢。
  • 如果你输入$string = "http://www.example.com/",并通过first preg_replace() 运行它,var_dump() 告诉你它是什么?
  • 更新了答案。将$1 更改为$0。我自己测试了preg_replace(),现在应该可以了。
  • 我没有让数字成为子域之后 URL 的第一部分(正如您在问题中所建议的那样)。我更新了模式以允许它们。 www.222test.com 现在可以正确匹配。还提供了 edit 3,它应该有助于解决您的 http:// 问题。
  • 我的错,我忘记了 $string 不是只是 URL。更新后的 edit 3 应该可以工作。抱歉修改了这么多! :P
【解决方案2】:

上面所有的例子我都有问题。

这是一个有效的方法:

function autolink($string){
        $string= preg_replace("#http://([\S]+?)#Uis", '<a href="http://\\1">\\1</a>', $string);
        return $string;
}

【讨论】:

    猜你喜欢
    • 2020-03-14
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-31
    相关资源
    最近更新 更多