正则表达式捕获子模式$2返回空值的原因解析
问题分析与解决
你的问题出在正则捕获组的定义和引用不匹配上,让我一步步给你拆解清楚:
先看你原正则的分组结构
原正则:
/(http|https|ftp|ftps)\:\/\/www\.[a-zA-Z0-9]{5}\.com(\w*)(\/\S*)?/
这里的捕获组是按括号出现的顺序编号的:
$1→ 匹配http/https/ftp/ftps协议部分$2→ 匹配(\w*),也就是.com后面的字母/数字/下划线,但你的目标URL.com后直接是/index.html,/不属于\w的范围,所以这个组匹配到的是空字符串$3→ 匹配(\/\S*)?,也就是/index.html路径部分
而你想要引用的那个5位域名(比如abcde),根本没有被定义为捕获组,自然没法通过$2拿到它。
修正方案
把那个5位的域名部分用括号括起来,作为第二个捕获组,然后调整替换语句里的引用编号:
修正后的代码:
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/www\.([a-zA-Z0-9]{5})\.com(\w*)(\/\S*)?/"; echo preg_replace($reg_exUrl, '<a href="$1://www.$2.com$3$4">$1://www.$2.com$3$4</a>','http://www.abcde.com/index.html');
现在的分组对应关系:
$1→ 协议部分(http/https等)$2→ 5位域名(abcde)$3→.com后可能存在的字母/数字/下划线(这里为空)$4→ 路径部分(/index.html)
运行这段代码,输出就会变成你期望的:
<a href="http://www.abcde.com/index.html">http://www.abcde.com/index.html</a>
额外优化建议
如果你的场景里.com后面不会有\w*这类字符(比如直接跟路径或结束),可以简化正则,去掉多余的(\w*)分组,让正则更简洁:
$reg_exUrl = "/(http|https|ftp|ftps)\:\/\/www\.([a-zA-Z0-9]{5})\.com(\/\S*)?/"; echo preg_replace($reg_exUrl, '<a href="$1://www.$2.com$3">$1://www.$2.com$3</a>','http://www.abcde.com/index.html');
这样分组更少,也能达到同样的效果。
内容的提问来源于stack exchange,提问作者hd.
相关产品推荐
相关产品推荐

