0

我正在处理一个网页,正则表达式不断出现,作为处理我试图解决的问题的字符串操作的最佳方式。不幸的是,正则表达式并不是微不足道的,我一直遇到麻烦。任何帮助表示赞赏;

我想将从 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>"

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

4

1 回答 1

2

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

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

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

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

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

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

编辑(14 年 8 月 2 日):正如下面的评论中所指出的,这与 .co.uk 之类的顶级域名不匹配。这是一个:

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

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

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

对于 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等函数的参数,然后您可以使用获取视频的 YouTube ID 'examplevide',然后使用它你想要。另请注意,正则表达式仅匹配 ID 的 11 个字符。$matches[1]

此正则表达式将匹配几乎所有当前的 youtube url 格式,包括不正确的情况和(正常)顺序参数:

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
于 2013-09-24T04:40:43.897 回答