JavaScript regex to capture a URL without query string

By

Learn how to use a JavaScript regular expression to capture a URL without its query string parameters, removing anything after the ? or # symbol.

~~~

Here’s the regex that captures a URL without its query string parameters:

/^(http[^?#]+).*/gm

I had the need to capture a URL without query parameters, for both http and https links, and this is what I came up with.

(Want to tweak it for your case? Paste it into my regex tester to see the matches live.)

Here’s an example:

const regex = /^(http[^?#]+).*/gm
const result = regex.exec("https://test.com?test=2")
console.log(result)

/*
[ 'https://test.com?test=2', 
'https://test.com', 
index: 0, 
input: 'https://test.com?test=2', 
groups: undefined ]
*/

JavaScript code editor showing regex execution with https://test.com URL and console output array result

The first element of the array is the full match. The clean URL is the captured group, at index 1. So result[1] gives you 'https://test.com'.

How the regex works

Let’s break it down:

The capture stops at the first ? or #. That means the regex strips fragments too, not just query strings:

const regex = /^(http[^?#]+).*/
'https://flaviocopes.com/tags/js/?page=2'.match(regex)[1]
//'https://flaviocopes.com/tags/js/'

'https://flaviocopes.com/blog/#topics'.match(regex)[1]
//'https://flaviocopes.com/blog/'

Watch out for the g flag with exec()

Be careful with one thing. When a regex has the g flag, exec() remembers where the last match ended, in the lastIndex property. Calling it again on the same regex object continues from there:

const regex = /^(http[^?#]+).*/gm
regex.exec('https://test.com?test=2') //matches
regex.exec('https://test.com?test=2') //null!

The second call returns null because the regex starts searching past the end of the previous match. If you’re testing one URL at a time, drop the g flag, or use string.match() as I did above.

The gm flags are useful when you have many URLs in a multiline string and want to process them all: g finds every match, m makes ^ match the start of each line.

~~~

Related posts about js: