如何解决regex-排除字符串的超前查询
| 我试图在文本中查找所有部分(并用其他替换) 从...开始 \'/\' 以。。结束 \'/\' 在两个/ \之间,除了字符串\'。\'和\'.. \'外,什么都可以。 (对于您的信息,我正在搜索并替换目录和文件名,因此应排除\'。\'和\'.. \'。) 这是我想出的正则表达式:/(?!\\.|\\.\\.)([^/]+)/
第二部分
([^/]+)
匹配每个字符序列,不包括\'/ \'。不需要字符限制,我只是在解释输入内容。
第一部分
(?!\\.|\\.\\.)
使用否定的超前断言排除字符串\'。\'和\'.. \'。
但是,这似乎不适用于mb_ereg_replace()的PHP。
有人可以帮我吗?我看不到我的正则表达式有什么问题。
谢谢。
解决方法
POSIX正则表达式可能不支持负前瞻。 (尽管我可能是错的)
无论如何,由于PCRE regex通常比POSIX快,我认为您可以使用相同功能的PCRE版本,因为PCRE也支持utf8并使用
u
标志。
考虑以下代码作为替代:
preg_replace(\'~/(?!\\.|\\.\\.)([^/]+)/~u\',\"\",$str);
编辑:更好的是使用:
preg_replace(\'~/(?!\\.)([^/]+)/~u\',$str);
, 这有点冗长,但确实可以使用:
#/((\\.[^./][^/]*)|(\\.\\.[^/]+)|([^.][^/]*))/#
^ |------------| |---------| |---------|
| | | |
| | text starting with |
| | two dots,that isn\'t |
| | \".\" or \"..\" |
| text starting with |
| a dot,that isn\'t text not starting
| \".\" or \"..\" with a dot
|
delimiter
不匹配:
hi
//
/./
/../
符合:
/hi/
/.hi/
/..hi/
/...
/
在http://regexpal.com/上尝试一下。
我不确定你是否愿意付//
。如果这样做,请在最后一个/
之前贴*
。
, 我不反对正则表达式,但是我应该这样做:
function simplify_path($path,$directory_separator = \"/\",$equivalent = true){
$path = trim($path);
// if it\'s absolute,it stays absolute:
$prepend = (substr($path,1) == $directory_separator)?$directory_separator:\"\";
$path_array = explode($directory_separator,$path);
if($prepend) array_shift($path_array);
$output = array();
foreach($path_array as $val){
if($val != \'..\' || ((empty($output) || $last == \'..\') && $equivalent)) {
if($val != \'\' && $val != \'.\'){
array_push($output,$val);
$last = $val;
}
} elseif(!empty($output)) {
array_pop($output);
}
}
return $prepend.implode($directory_separator,$output);
}
测试:
echo(simplify_path(\"../../../one/no/no/../../two/no/../three\"));
// => ../../../one/two/three
echo(simplify_path(\"/../../one/no/no/../../two/no/../three\"));
// => /../../one/two/three
echo(simplify_path(\"/one/no/no/../../two/no/../three\"));
// => /one/two/three
echo(simplify_path(\".././../../one/././no/./no/../../two/no/../three\"));
// => ../../../one/two/three
echo(simplify_path(\".././..///../one/.///./no/./no/../../two/no/../three/\"));
// => ../../../one/two/three
我认为最好返回一个等效的字符串,因此在字符串开始时我尊重..
的出现。
如果您不想要它们,则可以使用第三个参数$ equivalent = false调用它:
echo(simplify_path(\"../../../one/no/no/../../two/no/../three\",\"/\",false));
// => one/two/three
echo(simplify_path(\"/../../one/no/no/../../two/no/../three\",false));
// => /one/two/three
echo(simplify_path(\"/one/no/no/../../two/no/../three\",false));
// => /one/two/three
echo(simplify_path(\".././../../one/././no/./no/../../two/no/../three\",false));
// => one/two/three
echo(simplify_path(\".././..///../one/.///./no/./no/../../two/no/../three/\",false));
// => one/two/three
, /(?!(\\.|\\.\\.)/)([^/]+)/
这将允许使用“ 23”作为有效名称。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。