假设我有两个不同版本的链接发布在我的网站上。。。
- https://vine.co/v/iF20jKHvnqg
- https://vine.co/v/iF20jKHvnqg/
(差异为尾随/)
一旦帖子在我的网站上提交,它们就会变成超链接,看起来如下:
<a href="https://vine.co/v/iF20jKHvnqg" target="_blank">https://vine.co/v/iF20jKHvnqg</a>
我已经设置了一个preg替换来捕获vine链接并将其转换为嵌入(这条帖子消息显然包含更多内容,但这是为了示例:
$this->post['message'] = '<a href="https://vine.co/v/iF20jKHvnqg" target="_blank">https://vine.co/v/iF20jKHvnqg</a>';
$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']);
我使用通配符(.*)
,我认为它的意思是"任何东西",但出于某种原因,如果链接是用尾部斜杠发布的,它不会被转换。。。
我尝试过将我的reg ex更改为(只是我尝试过的几个例子)
~(<a href="https?://vine.co)/v/(.*)/" target="_blank">(https?://vine.co)/v/(.*)/<'/a>~
然后转换带有尾部反斜杠的链接并忽略不带的链接。
~(<a href="https?://vine.co)/v/(.*)/?" target="_blank">(https?://vine.co)/v/(.*)/?<'/a>~
我只是觉得也许是?我使用https检查也会做同样的事情,但什么都没做。
然后说嘿,等等,那不在reg ex中,所以我像一样尝试了一下
~(<a href="https?://vine.co)/v/(.*/?)" target="_blank">(https?://vine.co)/v/(.*/?)<'/a>~
但仍然没有运气。
如何使我的替换不在乎是否有尾随反斜杠?
如果您只需要这个非常特定的替换,您可以直接连接字符串。
$message = rtrim($post['message'], '/');
$message = sprintf('<iframe src="%s/embed/simple" width="480" height="480" frameborder="0"></iframe>', $message);
或者,如果您真的想使用preg_replace:
$pattern = '~https?://vine.co/v/([^/]+)~';
$this->post['message'] = preg_replace($pattern, $drc_embed_vine, $this->post['message']);
您的模式需要与输入字符串($this->post['message']
)相匹配。然后,将匹配结果($1
)放入最终字符串中。
为了不在乎后面的斜杠,只需考虑视频ID永远不会包含斜杠:显然,它是字母数字[a-zA-Z0-9]
。我们采用除带有([^/]+)
的尾部斜杠之外的所有字符。您可以将([a-z0-9])
与i
修饰符一起使用。
您在最后一个字符串上构建了一个模式,并试图将其与输入字符串匹配。
此脚本:
<?php
$message = 'https://vine.co/v/iF20jKHvnqg/';
$drc_embed_vine = '<iframe src="https://vine.co/v/'1/embed/simple" width="480" height="480" frameborder="0"></iframe>';
$pattern = '~https?://vine.co/v/([^/]+)/?~';
echo preg_replace($pattern, $drc_embed_vine, $message);
产生这个:
<iframe src="https://vine.co/v/iF20jKHvnqg/embed/simple" width="480" height="480" frameborder="0"></iframe>
编辑
根据您的评论,这里有一个新的模式,以匹配提交的URL上的链接:
$pattern = '~^(<[^>]+>)https?://vine.co/v/([^/]+)/?(</a>)$~';
这种模式可以匹配<a href="https://vine.co/v/iF20jKHvnqg" target="_blank">https://vine.co/v/iF20jKHvnqg</a>
。
替换字符串略有变化:
'<iframe src="https://vine.co/v/$2/embed/simple" width="480" height="480" frameborder="0"></iframe>'
所以我有这个测试脚本,它将替换你提到的iframe:的链接
<?php
$message = '<a href="https://vine.co/v/iF20jKHvnqg" target="_blank">https://vine.co/v/iF20jKHvnqg</a>';
$drc_embed_vine = '<iframe src="https://vine.co/v/$2/embed/simple" width="480" height="480" frameborder="0"></iframe>';
$pattern = '~^(<[^>]+>)https?://vine.co/v/([^/]+)/?(</a>)$~';
echo preg_replace($pattern, $drc_embed_vine, $message);
在我问的另一个问题中,它没有忽略尾部斜杠,只是将其全部删除。
$this->post['message'] = preg_replace('+/(["<])+', '$1', $this->post['message']);
rtrim无法工作,因为/不是字符串的最后一个。
下面是一个解析器示例:
$string = '<a href="https://vine.co/v/iF20jKHvnqg" target="_blank">https://vine.co/v/iF20jKHvnqg</a>';
$doc = new DOMDocument();
$doc->loadHTML($string);
$links = $doc->getElementsByTagName('a');
foreach($links as $link) {
if(preg_match('~^https?://vine'.co/v/([^/]+)~', $link->getAttribute('href'), $url)){
echo '<iframe src="https://vine.co/v/' . $url[1] . '/embed/simple" width="480" height="480" frameborder="0"></iframe>';
}
}
输出:
<iframe src="https://vine.co/v/iF20jKHvnqg/embed/simple" width="480" height="480" frameborder="0"></iframe>
演示:https://eval.in/569642