区分正则表达式中两个几乎相同的链接

时间:2016-05-16 23:27:21

标签: php regex facebook comments vbulletin

我创建了一个插件,可以将链接转换为链接内容的Facebook嵌入版本。我的问题是如果我禁用插件的部分注释,注释的链接将成为嵌入式帖子(如果插件的帖子部分仍处于活动状态)。

让我们来看看,所以我们有3个链接:

Facebook帖子

<a href="https://www.facebook.com/zuck/posts/10102577175875681" target="_blank">ONE</a>

注释

<a href="https://www.facebook.com/zuck/posts/10102577175875681?comment_id=1193531464007751" target="_blank">Two</a>

并回复评论

<a href="https://www.facebook.com/zuck/posts/10102577175875681?comment_id=1193531464007751&reply_comment_id=10102577641662241" target="_blank">Three</a>

所有三个链接都以

开头
https://www.facebook.com/zuck/posts/10102577175875681

在下面的代码中,if条件是我的设置toggles,并且此帖子消息等于用户发布的内容,因此在此示例中此帖子消息等于上面的三个链接。

这是我为转换这些链接而创建的插件。

if ($this->registry->options['drcae_facebook_comment_onoff']) {
  // swaps facebook comment links to embed code
  $drc_embed_facebook_cmt = '<div class="fb-comment-embed" data-include-parent="true" data-width="560" data-href="https://www.facebook.com/$3/posts/$4comment_id=$5"></div>';
  $this->post['message'] = preg_replace('~<a (.*)href="(.*)facebook.com/(.*)/posts/(.*)?comment_id=(.*)"(.*)<\/a>~', $drc_embed_facebook_cmt, $this->post['message']);
}

if ($this->registry->options['drcae_facebook_post_onoff']) {
  // swaps facebook post links to embed code
  $drc_embed_facebook_post = '<div class="fb-post" data-href="https://www.facebook.com/$3/posts/$4"></div>';
  $this->post['message'] = preg_replace('~<a (.*)href="(.*)facebook.com/(.*)/posts/(.*)"(.*)<\/a>~', $drc_embed_facebook_post, $this->post['message']);
}

我确实在另一个方向翻了一下(帖子是第一个)但是这导致评论嵌入帖子,我通过首先检查评论来解决这个问题,这可能不是最好的方法。

所以你可能已经注意到了我的正则表达式,它并不是最好的,但是我能够自己完成正则表达式的新工作。

~<a (.*)href="(.*)facebook.com/(.*)/posts/(.*)"(.*)<\/a>~

我选择以这种方式执行我的正则表达式,所以如果链接的格式如下,它仍然会嵌入:

<a target="blank" href="https://www.facebook.com/USERNAME/posts/1234567890" alt="facebook post">LINK</a>

但现在我第二次猜测我的工作,在搜索完之后没想出任何东西时,我想我会寻求一些帮助。

如何区分这些链接,以免发表评论/评论回复?

更新1,嵌入帖子

现在我的插件看起来像这样

$drc_embed_facebook_post = '<div class="fb-post" data-href="https://www.facebook.com/$2/posts/$3"></div>';
$this->post['message'] = preg_replace('~<a (.*?)facebook\.com/([^/]+)/[^/]+/([0-9]+)(?:[?][^0-9]+([0-9]+)(?:&(.+))?)?</a>~', $drc_embed_facebook_post, $this->post['message']);

正则表达式

~<a (.*?)facebook\.com/([^/]+)/[^/]+/([0-9]+)(?:[?][^0-9]+([0-9]+)(?:&(.+))?)?</a>~

我开始懒得什么?我相信......不限制www。 https:// ect ...(facebook.com之前的任何内容)

这部分有效,直接抓住帖子链接就是一些例子。

https://www.facebook.com/RyanNewMe/posts/616837631826216?pnref=story
https://www.facebook.com/zuck/posts/10102833246942211?pnref=story
https://www.facebook.com/zuck/posts/10102830259184701?pnref=story

这些链接没有嵌入帖子。但是,如果我从中删除?pnref=story,则只有以下链接不起作用。

https://www.facebook.com/RyanNewMe/posts/616837631826216

1 个答案:

答案 0 :(得分:0)

我创建了一个很好的,快速的正则表达式来提取href earlier today,所以我将把它用作基线:

<a(?:\s*(?!href)[^\s>]*)*\s*href=["']([^"']+)

如果您使用此正则表达式,您将获得href属性的值作为匹配项。例如:

https://www.facebook.com/zuck/posts/10102577175875681

https://www.facebook.com/zuck/posts/10102577175875681?comment_id=1193531464007751

https://www.facebook.com/zuck/posts/10102577175875681?comment_id=1193531464007751&reply_comment_id=10102577641662241

然后你可以解析这一部分。

我制作了这个似乎有用的正则表达式:

facebook\.com/([^/]+)/[^/]+/([0-9]+)(?:[?][^0-9]+([0-9]+)(?:&(.+))?)?

您应该在$1$2$3$4找到“zuck”,原始ID,评论ID以及其他所有内容分别是链接。 (是的,我在那里得到了 lazy ,你是否需要将链接的末尾分解成碎片?)

它看起来非常复杂,但实际上它是可以理解的。

  • facebook\.com/匹配facebook.com/

  • [^\]+匹配一个或多个非斜杠

  • ([0-9]+)捕获一个或多个号码

  • 此blob:(?:[?][^0-9]+([0-9]+)(?:&(.+))?)?指定可选扩展名(即结束? s)。

    • (?:)表示非捕获组(主要是为了避免增加$2$3的名称)。
    • [?][^0-9]+表示有?后跟一些非数字。
    • ([0-9]+)捕获数字
    • &(.+)&匹配,然后捕获字符串的其余部分。

编辑:关于你的更新,可以像这样修复正则表达式(除非我错过了这个问题):

~<a (.*?)facebook\.com/([^/]+)/[^/]+/([0-9]+)(?:[?][^0-9<]+([0-9]*)(?:&([^<]+))?)?</a>~