正则表达式:除非是http(s),否则删除方案(捕获负回顾模式)

3
我在正则表达式方面有些困惑。如何再次捕获负向回顾模式?
我试图删除 uri 的 scheme(包括“://”),除非它是 http/https。我已经完成了一半(或者我以为我完成了一半,下面的模式甚至无法编译),但我忘记了如何实际捕获负向模式: preg_replace( '~^(?
我该怎么做呢?

你为什么想要移除它?那会改变URI的语义。 - Gumbo
我正在验证一个URL,并且希望在用户没有提供它的情况下添加 http://。但是,如果用户提供了 ftp:// 作为方案,则 http://ftp://somedomain.com 实际上将使用 Zend_Uri(我将用它来验证)返回一个有效的主机,即:ftp。希望我的意思表达清楚。 :) - Decent Dabbler
@fireeyedboy:你不应该删除任何东西,只有在URI根本没有方案时才添加http:// - Gumbo
@Gumbo:啊,我现在明白你的意思了。嗯,确实是个好观点。感谢你指出来! - Decent Dabbler
@Gumbo:你说服我改变了我的计划。不过,出于好奇,是否有可能捕获负回顾模式?我以为可以,但现在我开始怀疑了。 - Decent Dabbler
显示剩余2条评论
2个回答

2

一个快速的想法:

preg_replace ('#^((http[s]{0,1}://)|([a-z]+://))#i', '$2', $uri);

1
你可以将[s]{0,1}写成s? - Gumbo
我不得不多次查看它才明白为什么这实际上是起作用的,但那真的很聪明。而且它做到了我需要的功能。谢谢! - Decent Dabbler
@Gumbo:没错,我已经将它改成了这样:'preg_replace('#^(https?://)|([a-z]+://)#i', '$1', $url); - Decent Dabbler
@Gumbo,我只是认为这样更易读。同样适用于括号,你的眼睛会更容易注意到 ( | ) - vbence

1
preg_replace('#^((?:.(?<!http))+://)#i', '', $uri);

不错!虽然 Gumbo 说服我采用另一种方法来达到我的目标,但这确实展示了我最初要寻找的东西。我也尝试将 httpspreg_replace('#^((?:.(?<!http|https))+://)#i', '', $uri); 结合使用,它也可以正常工作。非常好!谢谢。 - Decent Dabbler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接