[Another option]
I'd interpret the URL string first and after interpret what the interpretation returns for me (as a Abtract syntax tree).  The following commands block will eat the url string while the below loop is executing (or interpreting), constructing a representative array in steps!
var curChar,
    directoryPassed,//not yet
    expectGetValue,
    getContent="",
    getStarted,//? not started ($_GET)
    inPort,//not reading port
    portRead,//port not read yet
    state=0,//first state
    text="",
    urlTree=[];
for(;;){
    curChar=url.charAt(0);//first char
    if(state===0){
        //expects http... ws... file or https, for example.
        if(curChar===""){
            throw new Error("http:// expected.")
        }else if(curChar===":"){
            if(directoryPassed){
                throw new Error("Unexpected token.")
            }
            urlTree.push({type:"URLProtocol",value:text});
            text="";
            state=1
        }else{
            text+=curChar
        }
    }else if(state===1){
        //expects //...
        if(url.substring(0,2)==="//"){
            state=2;
            url=url.substring(1)
        }else if(curChar===""){
            throw new Error("// expected.")
        }
    }else{
        //expects anything correct: site.com/dir, localhost:8080, ?get=0, etc.
        if(getStarted){
            if(curChar==="="){
                if(text.length===0){
                    throw new Error("Unexpected token.")
                }else{
                    expectGetValue=true;
                    getContent=""
                }
            }else if(curChar==="&"){
                if(expectGetValue||text.length!==0)
                    urlTree.push({type:"Variable",name:text,value: (getContent||true) });
                expectGetValue=false;
                text=""
            }else if(curChar===""){
                if(expectGetValue||text.length!==0)
                    urlTree.push({type:"Variable",name:text,value: (getContent||true) });
                break
            }else{
                if(expectGetValue){
                    getContent+=curChar
                }else{
                    text+=curChar
                }
            }
        }else if(curChar==="."){
            if(text.length===0){
                throw new Error("Unexpected token.")
            }else{
                if(inPort){
                    throw new Error("Unexpected token in port.")
                }else{
                    urlTree.push({type:"Name",value:text});
                    text=""
                }
            }
        }else if(curChar===""){
            if(text.length!==0){
                if(inPort){
                    urlTree.push({type:"Port",value:text})
                }else{
                    urlTree.push({type:"Name",value:text})
                }
                text=""
            }else if(inPort){
                throw new Error("Port not specified.")
            }
            break
        }else if(curChar==="?"){
            //$_GET starts here.
            if(text.length!==0){
                if(inPort){
                    urlTree.push({type:"Port",value:text})
                }else{
                    urlTree.push({type:"Name",value:text})
                }
                text=""
            }
            getStarted=true;
            urlTree.push({type:"Get"})
        }else if(curChar==="/"){
            if(text.length===0){
                throw new Error("Unexpected token.")
            }else{
                directoryPassed=true;
                if(inPort){
                    inPort=false;
                    urlTree.push({type:"Port",value:text})
                }else{
                    urlTree.push({type:"Name",value:text})
                }
                text="";
                urlTree.push({type:"NextDirectory"})
                //New directory!
            }
        }else if(curChar===":"){
if(portRead||text.length===0){
                throw new Error("Unexpected token.")
            }else{
                urlTree.push({type:"Text",value:text});
                text="";
                inPort=
                portRead=true;
                //Now the port will never be defined again.
            }
        }else if(inPort){
            if(/[0-9]/.test(curChar)){
                text+=curChar
            }else{
                throw new Error("Invalid port token.")
            }
        }else{
            text+=curChar
        }
    }
    url=url.substring(1)
}
Once it's ran, you get the urlTree array constructed with base in the url string. Additionaly, your URL currently returns the following tree in a array:

in the code. Every item from tree array is a object. Every object has the property type. type tolds what the item represents.
In this parsing, there are these types (in string):
"URLProtocol" -> It maybe http, https or anything else. Has the property: value (protocol string, as: "http", "ws", etc)
"Name" -> It's name of something. Example: name.name... name.com... ?name=0; Has the property: value (name string)
"NextDirectory" -> Represents "/" - "A new directory opened"
"Get" - > ? started. "Now URL variables maybe declared"
"Variable" -> represents ? variable. Has the properties: name and value;
Basic. That's all. Then you may interpret the array with a numeric loop with your own instructions.