src/URL/Normalizer.php
public function removeDotSegments($path)
    {
        $new_path = '';

        while (! empty($path)) {
             // A
            $pattern_a   = '!^(\.\./|\./)!x';
            $pattern_b_1 = '!^(/\./)!x';
            $pattern_b_2 = '!^(/\.)$!x';
            $pattern_c   = '!^(/\.\./|/\.\.)!x';
            $pattern_d   = '!^(\.|\.\.)$!x';
            $pattern_e   = '!(/*[^/]*)!x';

            if (preg_match($pattern_a, $path)) {
                // remove prefix from $path
                $path = preg_replace($pattern_a, '', $path);
            } elseif (preg_match($pattern_b_1, $path, $matches) || preg_match($pattern_b_2, $path, $matches)) {
                $path = preg_replace("!^" . $matches[1] . "!", '/', $path);
            } elseif (preg_match($pattern_c, $path, $matches)) {
                $path = preg_replace('!^' . preg_quote($matches[1], '!') . '!x', '/', $path);

                // remove the last segment and its preceding "/" (if any) from output buffer
                $new_path = preg_replace('!/([^/]+)$!x', '', $new_path);
            } elseif (preg_match($pattern_d, $path)) {
                $path = preg_replace($pattern_d, '', $path);
            } else {
                if (preg_match($pattern_e, $path, $matches)) {
                    $first_path_segment = $matches[1];

                    $path = preg_replace('/^' . preg_quote($first_path_segment, '/') . '/', '', $path, 1);

                    $new_path .= $first_path_segment;
                }
            }
        }

        return $new_path;
    }
public function removeDotSegments($path)
    {
        $new_path = '';

        while (! empty($path)) {
             // A
            $pattern_a   = '!^(\.\./|\./)!x';
            $pattern_b_1 = '!^(/\./)!x';
            $pattern_b_2 = '!^(/\.)$!x';
            $pattern_c   = '!^(/\.\./|/\.\.)!x';
            $pattern_d   = '!^(\.|\.\.)$!x';
            $pattern_e   = '!(/*[^/]*)!x';

            if (preg_match($pattern_a, $path)) {
                // remove prefix from $path
                $path = preg_replace($pattern_a, '', $path);
            } elseif (preg_match($pattern_b_1, $path, $matches) || preg_match($pattern_b_2, $path, $matches)) {
                $path = preg_replace("!^" . $matches[1] . "!", '/', $path);
            } elseif (preg_match($pattern_c, $path, $matches)) {
                $path = preg_replace('!^' . preg_quote($matches[1], '!') . '!x', '/', $path);

                // remove the last segment and its preceding "/" (if any) from output buffer
                $new_path = preg_replace('!/([^/]+)$!x', '', $new_path);
            } elseif (preg_match($pattern_d, $path)) {
                $path = preg_replace($pattern_d, '', $path);
            } else {
                if (preg_match($pattern_e, $path, $matches)) {
                    $first_path_segment = $matches[1];

                    $path = preg_replace('/^' . preg_quote($first_path_segment, '/') . '/', '', $path, 1);

                    $new_path .= $first_path_segment;
                }
            }
        }

        return $new_path;
    }
public function removeDotSegments ( $ path ) { $ new_path = '' ; while ( ! empty ( $ path ) ) { // A $ pattern_a = '!^(\.\./|\./)!x' ; $ pattern_b_1 = '!^(/\./)!x' ; $ pattern_b_2 = '!^(/\.)$!x' ; $ pattern_c = '!^(/\.\./|/\.\.)!x' ; $ pattern_d = '!^(\.|\.\.)$!x' ; $ pattern_e = '!(/*[^/]*)!x' ; if ( preg_match ( $ pattern_a , $ path ) ) { // remove prefix from $path $ path = preg_replace ( $ pattern_a , '' , $ path ) ; } elseif ( preg_match ( $ pattern_b_1 , $ path , $ matches ) || preg_match ( $ pattern_b_2 , $ path , $ matches ) ) { $ path = preg_replace ( "!^" . $ matches [ 1 ] . "!" , '/' , $ path ) ; } elseif ( preg_match ( $ pattern_c , $ path , $ matches ) ) { $ path = preg_replace ( '!^' . preg_quote ( $ matches [ 1 ] , '!' ) . '!x' , '/' , $ path ) ; // remove the last segment and its preceding "/" (if any) from output buffer $ new_path = preg_replace ( '!/([^/]+)$!x' , '' , $ new_path ) ; } elseif ( preg_match ( $ pattern_d , $ path ) ) { $ path = preg_replace ( $ pattern_d , '' , $ path ) ; } else { if ( preg_match ( $ pattern_e , $ path , $ matches ) ) { $ first_path_segment = $ matches [ 1 ] ; $ path = preg_replace ( '/^' . preg_quote ( $ first_path_segment , '/' ) . '/' , '' , $ path , 1 ) ; $ new_path .= $ first_path_segment ; } } } return $ new_path ; }
Path segment normalization
https://tools.ietf.org/html/rfc3986#section-5.2.4
Path segment normalization https : // tools . ietf . org / html / rfc3986#section - 5 . 2 . 4