Regex - negative scan to exclude rows

I try to find (and replace something else) in the text all the parts that

  • begin with '/'
  • ends with '/'
  • between them / can be anything but the lines '.' and "..".

(For your information, I search and replace the names of directories and files, so you should exclude "." And "..".)

This is the regular expression that I came up with:

/(?!\.|\.\.)([^/]+)/

The second part of

([^/]+)

matches each character sequence, '/' is excluded. There are no character restrictions, I just interpret the input.

First part

(?!\.|\.\.)

uses a negative expression to exclude strings. 'and "..".

However, this does not seem to work in PHP using mb_ereg_replace ().

Can someone help me? I do not see what is wrong with my regular expression.

Thank.

+5
4

Rexx POSIX, , . (, )

, PCRE , POSIX, , PCRE , PCRE utf8, u.

:

preg_replace('~/(?!\.|\.\.)([^/]+)/~u', "", $str);

EDIT: :

preg_replace('~/(?!\.)([^/]+)/~u', "", $str);
+4

, :

#/((\.[^./][^/]*)|(\.\.[^/]+)|([^.][^/]*))/#
^  |------------| |---------| |---------|
|        |             |               |
|        |        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/.

, //. , * /.

+3

regex, :

function simplify_path($path, $directory_separator = "/", $equivalent = true){
  $path = trim($path);
  // if it 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

I thought it would be better to return an equivalent string, so I respected the appearance ..at the beginning of the string.

If you do not want them, you can call it using the third parameter $ 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
+1
source

/(?!(\.|\.\.)/)([^/]+)/ This will allow ...as a valid name.

0
source

All Articles