Regex/Php:无法匹配实时网站中的问号


Regex/Php: Cannot match question mark in live site

我想删除网站上第一个"页面"项目的$_GET参数。

以下内容在我的本地服务器上的测试脚本中非常有效:

$urls = array(
'http://www.foo.com/bar.html?p=1',  //should match
'http://www.foo.com/bar.html?p=23',
'http://www.foo.com/bar.html?p=120',
'http://www.foo.com/bar.html?baz=123&p=1'  //should match
);
foreach ($urls as $url) {
    echo $url . '<br>';
    echo preg_replace('/(['?&]p=1)(?!'d)/', '', $url) . '<p>';
}

这产生:

http://www.foo.com/bar.html?p=1
http://www.foo.com/bar.html
http://www.foo.com/bar.html?p=23
http://www.foo.com/bar.html?p=23
http://www.foo.com/bar.html?p=120
http://www.foo.com/bar.html?p=120
http://www.foo.com/bar.html?baz=123&p=1
http://www.foo.com/bar.html?baz=123

然而,在现场,它从来没有匹配。

更糟糕的是,

str_replace('?p=1','',$url);

不会起作用。我错过了什么?我可以匹配一个问号,但一旦出现问题,我就倒霉了。str_replace和preg_replace都是这种情况。我觉得我错过了一些显而易见的东西,但我想不通。谢谢你的帮助。

解决方案:

在我的具体案例中,事实证明,Magento商店的底层系统已经发出了html_encoded字符。这一点,加上第一个参数是总是一个会话ID,它后来从URL字符串中删除,使我的任务像一样简单

$url = str_replace('&amp;p=1', '', $url); 

try''''''?而不是'';如果这不起作用,您可能会运行一个不支持负前瞻的regex引擎版本。

在这种情况下,您可以将您的preg_replace改为

preg_replace('/(['?&]p=1)([^'d])/', '$2', $url) . '<p>';

这将消耗非数字,但将其重新放入。可能有一些边缘情况下,这与您的正则表达式不同,但我认为您不会遇到那些带有URL的情况(我想不出任何URL)

当然,还有其他非正则表达式的解决方案,但由于正则表达式是一个非常强大的工具,了解它总是很好的;)