php 的 preg_replace 函数中的 正则表达式问题 为什么是 preg_replace("/(.*)[\/\\\]/",'',$text)
php的preg_replace函数中的正则表达式问题本想从aa\bb\cc或者aa/bb/cc这样的路径中提取cc的,但是preg_replace("/(.*)[\/\...
php 的 preg_replace 函数中的 正则表达式问题
本想从 aa\bb\cc 或者aa/bb/cc 这样的路径中提取cc的,但是 preg_replace("/(.*)[\/\\\]/",'',$text) 中的 "/(.*)[\/\\\]/" 为什么是三个 \\\, 而不是两个\\,即:
为什么是 preg_replace("/(.*)[\/\\\]/",'',$text) , 而不是 preg_replace("/(.*)[\/\\]/",'',$text) 。 展开
本想从 aa\bb\cc 或者aa/bb/cc 这样的路径中提取cc的,但是 preg_replace("/(.*)[\/\\\]/",'',$text) 中的 "/(.*)[\/\\\]/" 为什么是三个 \\\, 而不是两个\\,即:
为什么是 preg_replace("/(.*)[\/\\\]/",'',$text) , 而不是 preg_replace("/(.*)[\/\\]/",'',$text) 。 展开
3个回答
展开全部
转义是有两个地方的,一个是PHP解析器,一个是PHP内的正则表达式解析器。
PHP代码在运行的时候,所有使用引号的PHP常量都会被解析一次,字符串如果是一个正则表达式,交给正则引擎又会被解析一次。
所以,当表达式中要用到一个 \ 的时候,需要写两个,也就是 \\ 而当表达式需要两个的时候,需要写四个,也就是 \\\\。
当字符串 "\\\\" 经过PHP编译引擎的时候转义一次,得到 "\\" 这个字符串,然后再传递给正则引擎执行正则匹配,再被解析转义一次,得到 "\"
你的代码 preg_replace("/(.*)[\/\\\]/",'',$text) 中的表达式 "/(.*)[\/\\\]/" 经过PHP编译引擎后,得到的是 "/(.*)[\/\\]/" ,因为] 符号在PHP引擎中是不需要转义的,所以 \ 符号原样输出。当 "/(.*)[\/\\]/" 进入正则引擎的时候,解析得到 /(.*)[/\]/
引用的地址是PHP官方的解释:
replacement中可以包含后向引用\\n
或(php 4.0.4以上可用)$n, 语法上首选后者. 每个
这样的引用将被匹配到的第n个捕获子组捕获到的文本替换. n
可以是0-99, \\0和$0代表完整的模式匹配文本.
捕获子组的序号计数方式为: 代表捕获子组的左括号从左到右, 从1开始数. 如果要在replacement
中使用反斜线, 必须使用4个("\\\\", 译注: 因为这首先是php的字符串, 经过转义后, 是两个, 再经过
正则表达式引擎后才被认为是一个原文反斜线).
PHP代码在运行的时候,所有使用引号的PHP常量都会被解析一次,字符串如果是一个正则表达式,交给正则引擎又会被解析一次。
所以,当表达式中要用到一个 \ 的时候,需要写两个,也就是 \\ 而当表达式需要两个的时候,需要写四个,也就是 \\\\。
当字符串 "\\\\" 经过PHP编译引擎的时候转义一次,得到 "\\" 这个字符串,然后再传递给正则引擎执行正则匹配,再被解析转义一次,得到 "\"
你的代码 preg_replace("/(.*)[\/\\\]/",'',$text) 中的表达式 "/(.*)[\/\\\]/" 经过PHP编译引擎后,得到的是 "/(.*)[\/\\]/" ,因为] 符号在PHP引擎中是不需要转义的,所以 \ 符号原样输出。当 "/(.*)[\/\\]/" 进入正则引擎的时候,解析得到 /(.*)[/\]/
引用的地址是PHP官方的解释:
replacement中可以包含后向引用\\n
或(php 4.0.4以上可用)$n, 语法上首选后者. 每个
这样的引用将被匹配到的第n个捕获子组捕获到的文本替换. n
可以是0-99, \\0和$0代表完整的模式匹配文本.
捕获子组的序号计数方式为: 代表捕获子组的左括号从左到右, 从1开始数. 如果要在replacement
中使用反斜线, 必须使用4个("\\\\", 译注: 因为这首先是php的字符串, 经过转义后, 是两个, 再经过
正则表达式引擎后才被认为是一个原文反斜线).
参考资料: http://cn.php.net/manual/zh/function.preg-replace.php
展开全部
两个\\转义为\
\\]便转义为\],\]在程序理解为转义]
因为不能转义],所以要再加一个\,这样就不会让程序理解为转义]了,楼上说的也很清楚.
\\]便转义为\],\]在程序理解为转义]
因为不能转义],所以要再加一个\,这样就不会让程序理解为转义]了,楼上说的也很清楚.
追问
如果多加一个转义改成 preg_replace("/(.*)[\/\\\\]/",'',$text) ,又如何解析呢
追答
echo "\\";的结果是\
说明\被php内置编译引擎识别为特殊的转义符(当然了echo '\\';的结果也是\),要明白''和""在php中的区别
preg_replace("/(.*)[\/\\\]/",'',$text) 中的表达式 "/(.*)[\/\\\]/"因为先在""中所以第一遍被php内置编译引擎识别为"/(.*)[\/\\]".备注:\\被转义为\了。
第二遍被perl正则引擎识别为"/(.*)[\/\]";到此便完成解析,然后便是匹配了。
ps:\在脚本语言中是一个特殊的字符,而""在php脚本中也是一个很特殊的一对符号,两个在一起的时候有时候就要特殊对待了。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2012-07-29
展开全部
[\/\\\] 很好理解:正则式中\不能直接输出,需转义。知道这就看过程:
既然是转义所以他后面要跟要转义的东西,因此如果是2个斜杠的话\\】就变成转义];用算术的理解就是\(\]),先计算括号等于],然后在跟前\又构成了转义,结果是].但缺 少了一个需要匹配的\,所以再加一个 \,变成 \\ \],程序就理解前面是一个匹配,后面一组是一个匹配。相当起到分割语句的作用。
既然是转义所以他后面要跟要转义的东西,因此如果是2个斜杠的话\\】就变成转义];用算术的理解就是\(\]),先计算括号等于],然后在跟前\又构成了转义,结果是].但缺 少了一个需要匹配的\,所以再加一个 \,变成 \\ \],程序就理解前面是一个匹配,后面一组是一个匹配。相当起到分割语句的作用。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询