我有这个简单的dumy文本
<base href="http://wjbty.lc/"/?
<a href="common/home" />
<a href="common/home" />
<a href="/common/home" />
<a href="http://common/home" />
<a href="https://common/home" />
<a href="common/home" />
我的正则表达式是(?:(href="))(?!\/)(?!https:\/\/)(?!http:\/\/)(.*)"
并且其工作正常且匹配所有相对链接,但在结果匹配中始终包含href="
。
以及如何从结果中排除href="
。
任何人都可以测试它,然后请回答,因为有两个答案,但没有一个是有效的。
答案 0 :(得分:4)
在你的表达式中,你有一组额外的括号
(?:(href="))
应该是
(?:href=")
编辑: 我想你想要这个
/(?:href=")(?!\/)(?!https:\/\/)(?!http:\/\/)(.*)"/
所以它也没有捕捉到密切的报价。 还记得preg_match_all返回一个或多个数组 第一个数组是总捕获。 第二个数组是组捕获(你想要的)
额外参数
flags参数可以是PREG_PATTERN_ORDER或PREG_SET_ORDER
PREG_PATTERN_ORDER表示array [0]将是所有捕获信息,而array [1]将是您在括号中捕获的信息。
PREG_SET_ORDER表示每个匹配都有一个数组元素,匹配[0]是总信息,匹配[1]是捕获组。
答案 1 :(得分:1)
另一种继续的方法是使用\K
功能从匹配结果中排除模式开头匹配的子字符串(直到\K
)。例如:
\shref="\K(?!(?:https?:/)?/)[^"]+
建议:如果使用斜杠作为模式分隔符,则必须转义模式中的斜杠,但使用其他字符是更好的选择,例如~
。
请注意,您根本不需要捕获组,因为您要获取的是整个匹配。
如果您需要,可以在模式的末尾添加一个前瞻,以检查结束双引号是否存在:(?=")
答案 2 :(得分:0)
如果你想使用前瞻和后视,这应该是你的答案:
(?<=href=")(?!\/)(?!https:\/\/)(?!http:\/\/)(.*)(?=\")