求大牛解释下这个正则表达式:/^.+[\\\\\\/]/,最主要是为什么要那么多的转义字符,

当然了我理解他是想对\和/进行单选,但为什么要那么多。
function sbasename($filename)
{
return preg_replace('/^.+[\\\\\\/]/', '', $filename);
}
这是源码,网上copy,运行ok
功能是取得路径中的文件名称,因为basename()方法不能取得含有中文名称的文件

这个看语境的,理论上\\ 和\/就足够了,但是某些情况下这个字符串需要进行二次转义,所以\\就变成了\\\\,\/变成了\\/
比如$i = "\\\\\\/";
$reg = "/^.+" . $i . "/";追问

嗯,很好!但依然不理解有哪些情况需要进行二次转义。

追答

刚才说的有点乱,其实正则表达式本身就是需要二次转义的。是这样,对于字符串来说,'\'是需要转义的,如果你希望最后的结果是'\',那么必须用\\代替,这个可以明白撒?
然后,对于正则表达式来说,\和/都是特殊字符,所以必须使用\\和\/。
现在你的表达式写在引号里面,PHP解析器首先从引号中获取值,得到\\\/,然后正则表达式解析器解析\\\/得知你想要字符\和/
很绕嘴啊,解释清楚没?

追问

昂,非常理解!如你所说:^.+[\\\\\\/]其实可以写成^.+[\\\/],当然,如果我开始写的话也是写成这样
但是你开始说,需要二次转义:拆分开来看
首先,对\\前面的转义符二次转义,那么变成了\\\;然后对后面的(元字符)字符\转义,变成了\\\\,那么结果是两个\字符,但是结果的第一个字符被当做了转义后的转义符,那最终的结果只是一个\字符
对于\/,同样需要对前面的转义符二次转义,变为\\/。但为什么要二次转义

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-03-11
你好,在JS里只是对\和/进行单个匹配的话这样就可以了/[\\\/]/
在正则表达式里,中括号[] 里的内容是一个集合,同样的字符,多个和一个是同样的效果。追问

感谢专家!

来自:求助得到的回答
第1个回答  2013-03-11

我来告诉你吧!其实这代码是一个一堆人转载时候的误传,本身用

return preg_replace('/^.+[\\/]/', '', $filename);


就直接可以了。为毛多出那么多\\\\呢?由于\是敏感字符,某些网站会对\进行过滤。尤其是在php老版本(5.5已经没有了)默认开启magic_quotes_gpc时候,会对所有\进行添加\防止被黑。然后这个程序被转来转去,自动就加了很多个\

第2个回答  2013-03-11
两边的斜线(/)不看
正则是 ^.+[\\\\\\/]
^表示这个是开始位置
.表示除“\n”之外的任何单个字符
+表示匹配前面的那个字符1次或多次
[] 表示可选字符

下面这些都可以匹配:
ww\\\\\\\\\\
cc\
a\
bb//////////////////
b/
c/
kkkkkkk/
kkkkkkk\
kkkkkkk///

它跟 ^.+[\\/] 的效果是一样的。
至于它为什么要那么写3个反斜线,大概是因为他很闲吧。追问

\\\\\\/和\\/是不一样滴,我说了,在中括号里,他是想对\和/进行二选一。
\\/代表的是/,再前面\\代表的是\,我不理解的是为什么前面还有两个\转义符

追答

\\是转义\
/不需要转义
它的代码可能在用的时候需要转移\
比如C/C++:
char* regex = "\\\\";//这个正则是\\
char regex2 ="\\\\/";//这个正则是\\/
应该不是
\\\ \\\/
而是
\\ \\ \\ /
实际的正则应该是 \\/
这个/不需要转义,应该写成\\ \\ /

我没见过对/转义的。

追问

function sbasename($filename)
{
return preg_replace('/^.+[\\\\\\/]/', '', $filename);
}这是源码,copy的,运行OK

/属于非字母数字的特殊字符,进行转义以确保是安全的,代表/本身。书上和别人都进行了转义,最近的例子:下楼

来自:求助得到的回答本回答被网友采纳
第2个回答  2013-03-11
\\是正则的转义处理一些特殊字符的
\\\是\
*************************
\\\\是因为在winxp中需要前面在带一个\

那个就是带三个\\\加一个/就可以了

你写的那个怎么那么多\,O(∩_∩)O,是不是你搞错了追问

感谢!
代码是网上copy的,而且我运行也没有出错!所以...
function sbasename($filename)
{
return preg_replace('/^.+[\\\\\\/]/', '', $filename);
}
功能是取得路径中的文件名称,因为basename()方法不能取得含有中文名称的文件
\\\\是因为在winxp中需要前面在带一个\。这个真没听过

相似回答