private static function buildPatterns()
    {
        $alpha = 'A-Za-z';
        $digit = '0-9';
        $hex = $digit . 'A-Fa-f';
        $unreserved = "$alpha$digit\\-._~";
        $delimiters = "!$&'()*+,;=";
        $utf8 = '\\x80-\\xFF';

        $octet = "(?:[$digit]|[1-9][$digit]|1[$digit]{2}|2[0-4]$digit|25[0-5])";
        $ipv4address = "(?>$octet\\.$octet\\.$octet\\.$octet)";

        $encoded = "%[$hex]{2}";
        $h16 = "[$hex]{1,4}";
        $ls32 = "(?:$h16:$h16|$ipv4address)";

        $data = "[$unreserved$delimiters:@$utf8]++|$encoded";

        // Defining the scheme
        $scheme = "(?'scheme'(?>[$alpha][$alpha$digit+\\-.]*+))";

        // Defining the authority
        $ipv6address = "(?'IPv6address'" .
            "(?:(?:$h16:){6}$ls32)|" .
            "(?:::(?:$h16:){5}$ls32)|" .
            "(?:(?:$h16)?::(?:$h16:){4}$ls32)|" .
            "(?:(?:(?:$h16:){0,1}$h16)?::(?:$h16:){3}$ls32)|" .
            "(?:(?:(?:$h16:){0,2}$h16)?::(?:$h16:){2}$ls32)|" .
            "(?:(?:(?:$h16:){0,3}$h16)?::$h16:$ls32)|" .
            "(?:(?:(?:$h16:){0,4}$h16)?::$ls32)|" .
            "(?:(?:(?:$h16:){0,5}$h16)?::$h16)|" .
            "(?:(?:(?:$h16:){0,6}$h16)?::))";

        $regularName = "(?'reg_name'(?>(?:[$unreserved$delimiters$utf8]++|$encoded)*))";

        $ipvFuture = "(?'IPvFuture'v[$hex]++\\.[$unreserved$delimiters:]++)";
        $ipLiteral = "(?'IP_literal'\\[(?>$ipv6address|$ipvFuture)\\])";

        $port = "(?'port'(?>[$digit]*+))";
        $host = "(?'host'$ipLiteral|(?'IPv4address'$ipv4address)|$regularName)";
        $userInfo = "(?'userinfo'(?>(?:[$unreserved$delimiters:$utf8]++|$encoded)*))";
        $authority = "(?'authority'(?:$userInfo@)?$host(?::$port)?)";

        // Defining the path
        $segment = "(?>(?:$data)*)";
        $segmentNotEmpty = "(?>(?:$data)+)";
        $segmentNoScheme = "(?>([$unreserved$delimiters@$utf8]++|$encoded)+)";

        $pathAbsoluteEmpty = "(?'path_abempty'(?:/$segment)*)";
        $pathAbsolute = "(?'path_absolute'/(?:$segmentNotEmpty(?:/$segment)*)?)";
        $pathNoScheme = "(?'path_noscheme'$segmentNoScheme(?:/$segment)*)";
        $pathRootless = "(?'path_rootless'$segmentNotEmpty(?:/$segment)*)";
        $pathEmpty = "(?'path_empty')";

        // Defining other parts
        $query = "(?'query'(?>(?:$data|[/?])*))";
        $fragment = "(?'fragment'(?>(?:$data|[/?])*))";

        $absolutePath = "(?'hier_part'//$authority$pathAbsoluteEmpty|$pathAbsolute|$pathRootless|$pathEmpty)";
        $relativePath = "(?'relative_part'//$authority$pathAbsoluteEmpty|$pathAbsolute|$pathNoScheme|$pathEmpty)";

        self::$absoluteUri = "#^$scheme:$absolutePath(?:\\?$query)?(?:\\#$fragment)?$#";
        self::$relativeUri = "#^$relativePath(?:\\?$query)?(?:\\#$fragment)?$#";
        self::$scheme = "#^$scheme$#";
        self::$host = "#^$host$#";
    }