Php 预替换为带导斜线

Php 预替换为带导斜线,php,regex,Php,Regex,我想从URL中去掉前导斜杠和查询字符串,但无法同时解决这两个问题。我有这段代码,它非常适合剥离querystring,但它保留了前导斜杠 preg_replace('/\?.*$/', '', $_SERVER['REQUEST_URI']) 如果我的URL是www.mysite.com/myPage?querystring=123,以上内容将留给我/myPage。我如何调整它,以便也可以删除前导斜杠 另外,你能告诉我一个资源来帮助我理解preg\u replace模式匹配吗?在这种简单的情况

我想从URL中去掉前导斜杠和查询字符串,但无法同时解决这两个问题。我有这段代码,它非常适合剥离querystring,但它保留了前导斜杠

preg_replace('/\?.*$/', '', $_SERVER['REQUEST_URI'])
如果我的URL是
www.mysite.com/myPage?querystring=123
,以上内容将留给我
/myPage
。我如何调整它,以便也可以删除前导斜杠


另外,你能告诉我一个资源来帮助我理解
preg\u replace
模式匹配吗?

在这种简单的情况下,我可能更喜欢PHP的简单字符串函数而不是正则表达式:

$addr  = ltrim($_SERVER['REQUEST_URI'], '/'); // zap a leading slash
$q_pos = strpos($addr, '?'); // get the string position of a '?'
$addr  = $q_pos !== FALSE ? substr($addr, 0, $q_pos) : $addr; // pull out URI
PHP返回一个整数值,因此有可能
$q_pos===0
。。。这就是为什么我们要检查
$q_pos!==错误

更新

我想我应该回答这个问题,不过。。。所以在这种情况下要真正使用正则表达式

$address = '/test/url/test.php?extra';
$pattern = '{^/?([^\?]+)\?.*$}';
$replace = '$1';
$address = preg_replace($pattern, $replace, $address);
echo "$address"; // outputs: test/url/test.php
这是怎么回事?好。。。我们的模式使用括号指定一个捕获组
([^\?]+)
,该括号在可选的正斜杠
/?
之后获取所有内容,直到字符串中第一次出现可选的
\?
。注意,我们用反斜杠转义实际的问号字符,因为它在正则表达式模式的上下文中有意义。regex模式的最后一部分
*
只是将零个或多个字符匹配到字符串的末尾

最后,我们的替换只是指定
$1
来引用我们用原始括号分组
([^\?]+)
捕获的文本

需要注意的另一件事是,regex新手经常没有意识到,使用
/
作为模式定界符并不需要。在这样的情况下,我们匹配的是实际的正斜杠字符,我使用了其他东西(比如大括号)

我通常会建议正则表达式初学者帮助他们入门

更新2

上面的正则表达式假设总是有一个查询字符串,因此如果遇到一个没有查询字符串的URI(例如,
/All Products
),正则表达式将无法工作。为此,只需改变模式,使查询字符串成为可选的:

$pattern = '{^/?([^\?]+)(?:\?.*)?$}'; // use an optional non-capturing group
-或-

解释

  • {
  • ^/匹配第一个字符(如果它是 刀砍
  • |或
  • \?*匹配后跟零或零的文字问号 更多字符,直到字符串结束
  • }
在英语中,“如果第一个字符是斜杠或问号(包括问号)后的任何内容,请删除该字符”
具有特殊的含义,因此必须转义
\?

为什么不简单地使用这样的字符串函数可能不是正则表达式的工作,而是您选择的语言中的现有工具的工作。正则表达式并不是一根魔杖,你在遇到每一个涉及字符串的问题时都会挥舞它。您可能希望使用已经编写、测试和调试的现有代码。在PHP中,使用函数。Perl:。鲁比:。NET:谢谢你的帮助,但它仍然为我留下了第一个斜杠。我已经尝试过这个代码-对不起,我不知道如何格式化它$地址=$\u服务器['REQUEST\u URI']$模式=“{^/?([^\?]+)\?*$}”$替换=“$1”$地址=preg_replace($pattern,$replace,$address);echo$地址;我肯定遗漏了什么,因为你的答案似乎和我的原始代码产生了完全相同的结果。不过,感谢您提供了指向regex页面的链接,它应该会很有用:)好吧,既然您已经尝试让它自己工作,如果您能让我知道
echo$_SERVER['REQUEST_URI']的输出,我将提供帮助
来自$\u服务器['REQUEST\u URI']的输出是/All Products。谢谢你的帮助啊,所以如果你没有指定一些是可选的,整个正则表达式都会失败。谢谢你指出这一点!顺便说一句,代码很好用……谢谢!
$pattern = '{^/?([^\?]+)\??.*$}'; // make the escaped ? optional
$addr = preg_replace('{^/}','',$_SERVER['REQUEST_URI']);//removes leading slash
list($path) = explode('?',$addr);//removes query string
var_dump($path);
$path = preg_replace('{^/|\?.*}','',$_SERVER['REQUEST_URI']);