使用preg_replace将Twitter URL替换为带ID的div标签失败,求助解决方案
如何提取Twitter状态URL中的ID并替换为指定div标签?
我有如下字符串:
$string = " https://twitter.com/AdamaUK_/status/1262730246668922885 text https://twitter.com/wheat_daddy/status/1262629949908885511?s=20 text https://twitter.com/AdamaUK_/status/1262730246668922885 text https://twitter.com/wheat_daddy/status/1262629949908885511?s=30 ";希望通过
preg_replace()将其替换为:<div id='1262730246668922885'></div> text <div id='1262629949908885511'></div> text <div id='1262730246668922885'></div> text <div id='1262629949908885511'></div>我尝试了以下代码但未成功:
$pattern = "/(?i)\b((?:https?:\/\/|www\d{0,3}[.]|twitter+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'\".,<>?«»“”‘’]))/"; function getTweet($string) { return preg_replace($pattern, "<div id='$1'></div>", $string); }请问如何正确提取Twitter URL中的ID并成功替换为对应的div标签?感谢解答。
问题分析
你之前的正则主要有两个问题:
- 匹配范围太广:这个正则是通用的URL匹配规则,会匹配所有类型的链接,而不是仅针对Twitter的状态链接;
- 捕获内容错误:你用
$1捕获的是整个URL字符串,而不是我们需要的状态ID,所以替换后div的id会是完整URL,不符合需求。
解决方案
我们可以写一个更精准的正则,专门匹配Twitter状态链接的结构,直接捕获其中的状态ID部分:
完整代码实现
$string = " https://twitter.com/AdamaUK_/status/1262730246668922885 text https://twitter.com/wheat_daddy/status/1262629949908885511?s=20 text https://twitter.com/AdamaUK_/status/1262730246668922885 text https://twitter.com/wheat_daddy/status/1262629949908885511?s=30 "; // 精准匹配Twitter状态链接的正则 $pattern = "/https?:\/\/twitter\.com\/[^\/]+\/status\/(\d+)(?:\?\S*)?/i"; function getTweet($string, $pattern) { return preg_replace($pattern, "<div id='$1'></div>", $string); } // 输出结果 echo getTweet($string, $pattern);
正则规则详解
逐段拆解这个正则的作用:
https?:\/\/twitter\.com\/:匹配HTTP/HTTPS开头的Twitter域名,?允许省略s,\.转义点号避免匹配任意字符;[^\/]+:匹配Twitter用户名(除了斜杠的任意字符,直到下一个斜杠为止);\/status\/:匹配状态链接的固定路径部分;(\d+):核心捕获组,匹配一串数字(也就是我们需要的状态ID),后续用$1引用这个值;(?:\?\S*)?:非捕获组,匹配链接末尾的可选参数(比如?s=20),?表示这部分是可选的,\S*匹配任意非空白字符直到空格结束;/i:不区分大小写修饰符,兼容大写形式的URL(比如HTTPS://TWITTER.COM/...)。
额外优化
我把正则作为参数传入函数,避免了使用global变量,这样代码的耦合度更低,也更符合PHP的最佳实践。
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

