Regex to match accept-language header

Tags: , ,

I am trying to match the following accept-language header field of a http request.

var regex = /([^-]*)(?:-([^;]*))?(?:;q=([0-9].[0-9]))?/
"en-us;q=0.8".match(regex) => ["en-us;q=0.8", "en", "us", "0.8"]
"en".match(regex) => ["en", "en", undefined, undefined]
"en;q=0.8".match(regex) => ["en;q=0.8", "en;q=0.8", undefined, undefined]

The problem is in the last line. It should imho yield:

["en;q=0.8", "en", "0.8", undefined]

What is wrong with my regex?


Your first capturing group matches everything that doesn’t contain dashes and stops at a dash -. In your last string you have no dash, so it matches the entire string. The other parts of your regexp are optional, so they match nothing.

You can fix it for this particular case by not allowing ; in your first capturing group:


PS: I also fixed your dot in the last capturing group. It matched any character, now it matches only the . character.

Source: stackoverflow