从超链接href

时间:2016-05-12 18:25:56

标签: php hyperlink preg-replace trim

这与我上一篇文章的信息几乎相同,但这是一个不同的问题。

我有一个$this->post['message']的变量,这是用户发布的任何内容。

如果用户发帖:

Check out this vine https://vine.co/v/iF20jKHvnqg/

提交后,html输出如下:

Check out this vine <a href="https://vine.co/v/iF20jKHvnqg/" target="_blank">https://vine.co/v/iF20jKHvnqg/</a>

这就是$this->post['message']等于。

所以在我的后端我创建了一个插件

$drc_embed_vine =  '<iframe src="https://vine.co/v/$2/embed/simple" width="480" height="480" frameborder="0"></iframe>';

$this->post['message'] = preg_replace('~(<a href="https?://vine.co)/v/(.*)" target="_blank">(https?://vine.co)/v/(.*)<\/a>~', $drc_embed_vine, $this->post['message']);

这会在帖子中找到藤蔓链接,并将它们转换为iframe。我现在遇到了一个关于结束斜线的问题。

如果用户发布的https://vine.co/v/iF20jKHvnqg一旦提交后转为<a href="https://vine.co/v/iF20jKHvnqg" target="_blank">https://vine.co/v/iF20jKHvnqg</a>,则会转换为iframe罚款。

但是,如果用户发布的https://vine.co/v/iF20jKHvnqg/更改为<a href="https://vine.co/v/iF20jKHvnqg/" target="_blank">https://vine.co/v/iF20jKHvnqg/</a>,则会转换为$this->post['message'] = rtrim($this->post['message'],"/"); $drc_embed_vine = '<iframe src="https://vine.co/v/$2/embed/simple" width="480" height="480" frameborder="0"></iframe>'; $this->post['message'] = preg_replace('~(<a href="https?://vine.co)/v/(.*)" target="_blank">(https?://vine.co)/v/(.*)<\/a>~', $drc_embed_vine, $this->post['message']); 。差异是尾随斜杠。

现在我试过了:

$this->post['message']

但这似乎不起作用,有没有办法可以在$this->post['message']内定位藤蔓链接并删除尾部斜杠,甚至从{{1}内的任何链接中删除尾部斜杠}

所以,如果

$this->post['message'] = 'Go to <a href="http://stackoverflow.com/questions/ask/" target="_blank">http://stackoverflow.com/questions/ask/</a>';

它会变成

$this->post['message'] = 'Go to <a href="http://stackoverflow.com/questions/ask" target="_blank">http://stackoverflow.com/questions/ask</a>';

我目前主要专注于Vine链接,但是如果可以做到所有可能在长期内更好的链接。

我最近的失败尝试(我还在努力解决这个问题)

$drc_embed_vine =  '<iframe src="https://vine.co/v/$2/embed/simple" width="480" height="480" frameborder="0"></iframe>';
$str = $this->post['message'];
$str = rtrim($str, '/');
$str = preg_replace('~(<a href="https?://vine.co)/v/(.*)" target="_blank">(https?://vine.co)/v/(.*)<\/a>~', $drc_embed_vine, $str);

尝试了不同的东西 只是搞乱我给了他一个镜头

$str = $this->post['message'];
$str = rtrim($str, '/');

$this->post['message'] = $str;

所以帖子是

<a href="http://vine.co/v/iF20jKHvnqg/" target="_blank">http://vine.co/v/iF20jKHvnqg/</a>

rtrim无效= /

但如果我改变

$this->post['message'] = $str;

$this->post['message'] = test;

每个帖子都转到TEST所以我不明白为什么rtrim没有效果= /

更新清晰度

$this->post['message'] = 'Check out this vine <a href="http://vine.co/v/iF20jKHvnqg/" target="_blank">http://vine.co/v/iF20jKHvnqg/</a>';
$drc_embed_vine =  '<iframe src="https://vine.co/v/$2/embed/simple" width="480" height="480" frameborder="0"></iframe>';
$str = $this->post['message'];
$str = rtrim($str, '/');
$str = preg_replace('~(<a href="https?://vine.co)/v/(.*)" target="_blank">(https?://vine.co)/v/(.*)<\/a>~', $drc_embed_vine, $str);

正在进行更新!

在Richards回答之后,我玩了一下插件并想出了

$drc_embed_vine =  '<iframe src="https://vine.co/v/$2/embed/simple" width="480" height="480" frameborder="0"></iframe>';
$this->post['message'] = preg_replace('+/(["<])+', '$1', $this->post['message']);
$this->post['message'] = preg_replace('~(<a href="https?://vine.co)/v/(.*)" target="_blank">(https?://vine.co)/v/(.*)<\/a>~', $drc_embed_vine, $this->post['message']);

这个工作! =)但这是最有效的方式......?

2 个答案:

答案 0 :(得分:1)

参见下面的示例。我认为你的问题过于复杂,我没有看到代码正在处理$ post-&gt; ['message']的替换,或者生成iframe的链接。

但我试图让一个例子尽可能简单地模仿这个问题,你正试图解决

// input
$user = 'Check out this vine https://vine.co/v/iF20jKHvnqg/';
$after = 'Check out this vine <a href="https://vine.co/v/iF20jKHvnqg/" target="_blank">https://vine.co/v/iF20jKHvnqg/</a>';

// todo
$trim_user = rtrim($user, '/');
$trim_after = preg_replace('+/(["<])+', '$1', $after);

// output
echo "trim_user $trim_user\n";
echo "trim_after $trim_after\n";

因此,您可以拥有2个输入 - 来自$ user中用户的原始消息或$ after后面带有HTML链接的替换文本。

然后在$ user上,我只是测试rtrim,它可以工作。

在$ after之后,我需要替换所有出现的/之前的“或者&lt;。这是因为引号”“in和closing标签。我用两个正则表达式替换它们。

查看参数。 1st是正则表达式以匹配模式,2nd是匹配模式的替换,我正在跳过斜线/并且仅使用我需要保留的第二部分。

[] regexp中的方括号表示字符组 - 如[abc]是a,b或c中的任何字符。如果有的话 - 这是一个范围。像[a-z]是a和z之间的任何东西。

()括号表示一个组,它将根据组的顺序存储在$ 1,$ 2,$ 3中。在这种情况下,只有一组,所以我将它称为$ 1。

换句话说,/和“&lt;中的任何字符都会被”剪贴板“$ 1取代。这又是”或者&lt;。

最后,我正在将输出写入控制台。

trim_user Check out this vine https://vine.co/v/iF20jKHvnqg
trim_after Check out this vine <a href="https://vine.co/v/iF20jKHvnqg" target="_blank">https://vine.co/v/iF20jKHvnqg</a>

根据示例编辑

您可以避免在()中使用[^ /] *而不是。*来捕获/。

class Example
{

    public function run()
    {
        $this->post['message'] = 'Check out this vine <a href="http://vine.co/v/iF20jKHvnqg/" target="_blank">http://vine.co/v/iF20jKHvnqg/</a>';
        $drc_embed_vine = '<iframe src="https://vine.co/v/$2/embed/simple" width="480" height="480" frameborder="0"></iframe>';
        $str = $this->post['message'];
        $str = rtrim($str, '/');
        $str = preg_replace('~(<a href="https?://vine.co)/v/([^/]*)/?" target="_blank">(https?://vine.co)/v/(.*)<\/a>~', $drc_embed_vine, $str);

        echo $str;
    }
}

$example = new Example();
$example->run();

答案 1 :(得分:0)

试试这个

$str = $this->post['message'];
$str = rtrim($str, '/');