Php 正则表达式:否定断言

Php 正则表达式:否定断言,php,regex,Php,Regex,我一直使用一个简单的正则表达式来匹配内容中的URL。目标是从“/folder/id/123”等链接中删除该文件夹,并将其替换为“id/123”,使其成为同一文件夹中的相对较短的文件夹 事实上是的 $pattern = "/\/?(\w+)\/id\/(\d)/i" $replacement = "id/$2"; return preg_replace($pattern, $replacement, $text); 而且似乎效果不错 但是,我想做的最后一个测试是,如果每个匹配的url都是使用相同

我一直使用一个简单的正则表达式来匹配内容中的URL。目标是从“/folder/id/123”等链接中删除该文件夹,并将其替换为“id/123”,使其成为同一文件夹中的相对较短的文件夹

事实上是的

$pattern = "/\/?(\w+)\/id\/(\d)/i"
$replacement = "id/$2";
return preg_replace($pattern, $replacement, $text);
而且似乎效果不错

但是,我想做的最后一个测试是,如果每个匹配的url都是使用相同模式/文件夹/id/123的外部站点,那么它不包含http://

我尝试了/[^http://]或(?)?
$pattern=“/(?不需要精细PHP手册中的

请注意,明显相似的模式(?!foo)条找不到 在“bar”前面加上除“foo”以外的其他词的情况;它 查找任何出现的“bar”,因为断言 当后面三个字符为“bar”时,(?!foo)始终为真。A 为了达到这种效果,需要使用lookback断言

例如:

$pattern = "/(?<!http:\/)\/(\w+)\/id\/(\d)/i";

$pattern=“/(?好吧,谢谢,现在与http的链接不再匹配。太好了!Mhhh最后似乎没有匹配的内容:-/I没有任何替换内容。好吧,谢谢,我将尝试从您提供的链接中学习。好吧,
echo preg\u replace('/^(?!http)\/?(\w+\/node\/(\d)/I','id/$2','foo/node/123'));
echo的“id/123”给我。你可以测试和闲逛,直到这个模式适合你。而且,我也不想唠叨这个问题,但如果答案对你有帮助或解决了你的问题,习惯上投票或接受它;-)请提供一个例子。您的任务听起来很简单,但我看不到任何需要检查的字符串。您可以使用一个正则表达式来检查url是否以http开头,并在php if语句中使用另一个正则表达式来执行替换。这样更容易编写和理解,而且一个复杂的pcre甚至可能不会提高效率。
(these should be replaced, "same folder" => short relative path only)
<a href="/mysite_admin/id/414">label</a> ==> <a href="id/414">label</a>
<a href="/mYsITe_ADMIN/iD/29">label with UPPERCASE</a> ==> <a href="id/414">label with UPPERCASE</a>

(these should not be replaced, when there is http:// => external site, nothing to to)
<a href="http://mysite_admin/id/414">label</a> ==> <a href="http://mysite_admin/id/414">label</a>
<a href="http://www.google_admin.com">label</a> ==> <a href="http://www.google_admin.com">label</a>
<a href="http://anotherwebsite.com/id/32131">label</a> ==> <a href="http://anotherwebsite.com/id/32131">labelid/32131</a>
<a href="http://anotherwebsite_admin.com/id/32131">label</a> ==> <a href="http://anotherwebsite_admin.com/id/32131">label</a>
$pattern = "/(?<!http:\/)\/(\w+)\/id\/(\d)/i";