使用REGEX将www * .com更改为可点击的URL

时间:2013-09-24 03:36:29

标签: php regex

我正在开发一个网页,并且正在使用正则表达式作为处理我想要解决的问题的字符串操作的最佳方式。不幸的是,正则表达式并非完全无足轻重,我一直遇到麻烦。任何帮助表示赞赏;

我想将从php表单输入的字符串转换为可点击的链接。我的第一次挑战得到了帮助;如何使用http,https或ftp开头的字符串成为可点击的链接;

function make_links_clickable($message){
    return preg_replace('!(((f|ht)tp(s)?://)[-a-zA-Zа-яА-Я()0-9@:%_+.~#?&;//=]+)!i', '<a href="$1" target="_blank">$1</a>', $message);
}

$message = make_links_clickable($message);  

这很有效。当我看到它(并做一些研究)时,我可以从语法中收集到的最好的东西是第一部分匹配ftp,http和https,:和//以及各种组合模式。我想知道我怎么做;

1)建立以www开头的链接,或以.com / .net / .org / etc结尾的链接(如google.com或www.google.com - 省略http://)

2)更改像

这样的YouTube链接
"https://www.youtube.com/watch?v=examplevideo" 

进入

"<iframe width="560" height="315" src="//www.youtube.com/embed/examplevideo" frameborder="0" allowfullscreen></iframe>"

我认为这两种情况基本上是做同样的事情,但弄清楚并不直观。任何帮助都将深表感谢。

1 个答案:

答案 0 :(得分:2)

第一个正则表达式可以匹配几乎所有出现在ftp://,http://,https://之后的内容,所以最好将其他表达式作为单独的表达式来实现,因为它们只会匹配主机名。

对于1号,您需要决定您希望匹配不同TLD(.com / .net / etc)的严格程度。例如,您可以像这样显式匹配它们:

(www\.)?[a-z0-9\-]+\.(com|net|org)

但是,这只会匹配以.com,.net或.org结尾的网址。如果您想要所有顶级域并且只需要有效域,则需要手动将它们全部写入到最后。或者,你可以这样做,

(www\.)?[a-z0-9\-]+\.[a-z]{2,6}

将接受任何看起来像网址并以“点”结尾的内容,以及2到6个字母(.museum和.travel)的任意组合。但是,这将匹配“fgs.fds”之类的字符串。根据您的应用程序,您可能需要向[a-z]添加更多字符,以添加对扩展字符字母表的支持。

编辑(8月14日):正如下面的评论所指出的,这与.co.uk等TLD不符。这是一个:

(www\.)?[a-z0-9\-]+\.([a-z]{2,3}(\.?[a-z]{2,3})?)

而不是两个到六个字符之间的任何字符串(在句点之后),这将匹配任何两到三个,然后是另一个到三个(如果存在),有或没有分割期。

这是多余的,但你可以在第二个选项上的www之后删除问号,然后进行两个测试;这样,您可以匹配以通用TLD结尾的任何字符串,或以“www”开头的字符串。然后是任何带有一个句点的字符,“gpspps.cobg”。它仍然会匹配可能实际上不存在的网站,但至少它看起来像一个网址,它看起来就像一个。

对于YouTube版本,我疯了一点问题。

(?i:(?:(?:http(?:s)?://)?(?:www\.)?)?youtu(?:\.be/|be\.com/watch\?(?:[a-z0-9_\-\%\&\=]){0,}?v\=))([a-zA-Z0-9_\-]{11}){0,}?v\=))(?i)([a-zA-Z0-9_\-]{11})
编辑:我刚试过在我自己的一个项目中使用上面的正则表达式,但是我遇到了一些错误。我稍微改了一下,我认为这个版本可能更好:

(?i:(?:(?:http(?:s)?://)?(?:www\.)?)?youtu(?:\.be/|be\.com/watch\?(?:[a-z0-9_\-\%\&\=]){0,})?)(?:v=)?([a-zA-Z0-9_\-]{11})

对于那些不熟悉正则表达式的人,括号( ...regex... )被存储为组,可以从匹配的字符串中选择性地选择。以?:开头的括号组与在那里的大多数括号组(?:www\.)一样,但未在组内捕获。由于该正则表达式的结尾保留为普通“捕获”组([a-zA-Z0-9_\-]{11}),因此您使用preg_match等函数的$matches参数,然后可以使用$matches[1]获取视频的YouTube ID,“examplevide”,然后按照您的喜好使用它。另请注意,正则表达式仅匹配ID的11个字符。

这个正则表达式几乎可以匹配任何当前的youtube网址格式,包括不正确的情况和(正常)订单参数:

http://youtu.be/dQw4w9WgXcQ
https://www.youtube.com/watch?v=dQw4w9WgXcQ
http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=featured
http://www.youtube.com/watch?feature=featured&v=dQw4w9WgXcQ
http://WWW.YouTube.Com/watch?v=dQw4w9WgXcQ
http://YouTube.Com/watch?v=dQw4w9WgXcQ
www.youtube.com/watch?v=dQw4w9WgXcQ