我试图在文本的所有部分中找到(并用其他东西替换)
(有关您的信息,我正在搜索并替换目录和文件名,因此应排除'。'和'..'。)
这是我提出的正则表达式:
/(?!\.|\.\.)([^/]+)/
第二部分
([^/]+)
匹配每个字符序列,'/'被排除在外。不需要字符限制,我只是解释输入。
第一部分
(?!\.|\.\.)
使用负前瞻断言来排除字符串'。'和'..'。
但是,这似乎不适用于使用mb_ereg_replace()的PHP。
有人可以帮帮我吗?我没有看到我的正则表达式出了什么问题。
谢谢。
答案 0 :(得分:4)
POSIX正则表达式可能不支持负向前瞻。 (虽然我可能错了)
无论如何,因为PCRE正则表达式通常比POSIX快,我认为你可以使用相同功能的PCRE版本,因为PCRE支持utf8以及使用u
标志。
将此代码视为替代:
preg_replace('~/(?!\.|\.\.)([^/]+)/~u', "", $str);
preg_replace('~/(?!\.)([^/]+)/~u', "", $str);
答案 1 :(得分:3)
这有点冗长,但它确实有效:
#/((\.[^./][^/]*)|(\.\.[^/]+)|([^.][^/]*))/#
^ |------------| |---------| |---------|
| | | |
| | 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/上进行游戏。
我不确定您是否允许//
。如果您这样做,请在最后*
之前坚持/
。
答案 2 :(得分:1)
我不反对正则表达式,但我会这样做:
function simplify_path($path, $directory_separator = "/", $equivalent = true){
$path = trim($path);
// if it's absolute, it stays absolute:
$prepend = (substr($path,0,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
答案 3 :(得分:0)
/(?!(\.|\.\.)/)([^/]+)/
这将允许...
作为有效名称。