我有一个php字符串$ tweet,看起来像这样......
This is a sample tweet https://tr.co/sdfhnjn3
但有时它看起来像这样......
This is a sample tweet <a href="https://tr.co/sdfhnjn3">https://tr.co/sdfhnjn3</a>
我希望将所有https://tr.co链接转换为实际的href链接,除非它们已经采用该格式。
我知道我可以使用Regex转换链接,但我是否也可以检查它们是否已经是使用它的链接?
答案 0 :(得分:1)
要匹配并替换只有尚未链接的网址,请尝试使用此正则表达式:~(?<!href=['"])https?://[\w/._\-&?]*(?!</a>)(?=[^\w/._\-&])~gs
。
您可以在此处查看演示:https://regex101.com/r/BF8HBO/1。
然后将其与preg_replace
:
$string = preg_replace('~(?<!href=['"])https?://[\w/._\-&?]*(?!</a>)(?=[^\w/._\-&])~gs', '<a href="$0">$0</a>', $string);`;
注意:也请在regex101中检查替换面板,看看链接是否仅在尚未放置的情况下放置。
<强>详情:强>
~
作为分隔符,因为它在正则表达式主体中不常遇到,因此您不需要像/
(?<!href=['"])
这是一个负面的背后隐藏,可确保链接前面没有href=
以及'
或"
https?://[\w/._\-&?]*
匹配以http://
或https://
[\w/._\-&?]*
这匹配任何字母数字字符或其中一个/._?&-
通常出现在链接中的字母(?!</a>)
这是一个负面的预测,确保链接后面没有结尾</a>
(?=[^\w/._\-&])
这是一个积极的先行,确保链接后的下一个字符不是/._-&
之一,也不是字母数字字符(否则它们应该是链接的一部分)另一个注意事项: PHP有一个很好的正则表达式引擎(PCRE),允许外观,尤其是外观!不幸的是,这不是javascript等其他语言的情况。但总有一个(复杂的)解决方法! :)
同样,lookbehinds必须有一个固定宽度的字符,而不像前瞻。
答案 1 :(得分:0)
此代码将使用指向该URL的链接替换所提供的$ message中的任何url
$message = preg_replace('$(\s|^)(https?://[a-z0-9_./?=&-]+)(?![^<>]*>)$i', ' <a href="$2" target="_blank">$2</a> ', $message." ");
事实上,你也可以转换没有协议(http)部分的网址,只要它以www开头,它就可以传递一个有效的网址。
$message = preg_replace('$(\s|^)(www\.[a-z0-9_./?=&-]+)(?![^<>]*>)$i', '<a target="_blank" href="http://$2" target="_blank">$2</a> ', $message." ");
答案 2 :(得分:0)
您无需使用极其复杂的语法来尝试匹配网址的各个部分,就可以使用(*SKIP)(*FAIL)
取消已标记的网址的资格,然后仅匹配您域中的网址。
$tweets = [
'This is a sample tweet https://tr.co/sdfhnjn3',
'This is a sample tweet <a href="https://tr.co/sdfhnjn3">https://tr.co/sdfhnjn3</a>',
'This is a sample tweet https://example.com/sdfhnjn3',
'This is a sample tweet <a href="https://example.com/sdfhnjn3">https://example.com/sdfhnjn3</a>'
];
var_export(preg_replace('~<a [^>]+>.*?</a>(*SKIP)(*FAIL)|https?://(?:www)?tr.co/\S*~', '<a href="$0">$0</a>', $tweets));
输出:
array (
0 => 'This is a sample tweet <a href="https://tr.co/sdfhnjn3">https://tr.co/sdfhnjn3</a>',
1 => 'This is a sample tweet <a href="https://tr.co/sdfhnjn3">https://tr.co/sdfhnjn3</a>',
2 => 'This is a sample tweet https://example.com/sdfhnjn3',
3 => 'This is a sample tweet <a href="https://example.com/sdfhnjn3">https://example.com/sdfhnjn3</a>',
)
*只有第一个元素实际被更新,其他元素没有资格。