# Challenge: correctly handling Accept-Language HTTP header

**URL:** <https://www.ruby-forum.com/t/challenge-correctly-handling-accept-language-http-header/72928>\
**Category:** Ruby\
**Created:** [October 19, 2006, 11:33pm UTC](https://www.ruby-forum.com/t/challenge-correctly-handling-accept-language-http-header/72928 "2006-10-19T23:33:51Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [October 19, 2006, 11:33pm UTC](https://www.ruby-forum.com/t/challenge-correctly-handling-accept-language-http-header/72928/1 "2006-10-19T23:33:51Z")

</div>

I’ve been pondering the best way of writing a piece of code that will,  
when given a list of language options, select the one that best  
fullfills  
what is being requested in an Accept-Language header.

i.e.

If one has a list of en, en-gb and es, and one gets an Accept-Language  
header like this:

es-mx,es;q=0.8,en-us;q=0.5,en;q=0.3

the code would return the ‘es’ as the best matching language option.

Is there some already written Ruby code hiding in a project somewhere to  
do this? Is there some piece of C library somewhere that I could just  
write an extension for to do it? Can someone offer up a fast Ruby  
implementation to handle Accept-Language decisions?

I’ve hacked out an almost right approach, but I’m not happy with it.

Thanks,

Kirk H.

---

<div class="post-metadata">

**Author:** ![unknown](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/u/4bbf92/32.png) [@unknown](https://www.ruby-forum.com/u/unknown)\
**Post date:** [October 20, 2006, 2:52am UTC](https://www.ruby-forum.com/t/challenge-correctly-handling-accept-language-http-header/72928/2 "2006-10-20T02:52:18Z")

</div>

removed\_email\_address@domain.invalid wrote:

> If one has a list of en, en-gb and es, and one gets an Accept-Language  
> header like this:
> 
> es-mx,es;q=0.8,en-us;q=0.5,en;q=0.3
> 
> the code would return the ‘es’ as the best matching language option.

I have some doubts you’ll ever see that sort of header in the wild.

Besides, parsing that one is hardly something that needs a C library.

Here’s an almost-one-liner, if you’re willing to forgive the each block  
being three statements and remove all whitespace (it actually parses…)

“es-mx,es;q=0.8,en-us;q=0.5,en;q=0.3”.split(",").map { | i |  
i.split(";")  
}.each { | i |  
i[1] =~ /q=(\d+.\d+)/;  
i[1] = $1 && $1.to\_f || 1.0  
}.sort\_by{ | i |  
i[1]  
}.reverse[0][0]

=\> “es-mx”

(The quality value for es-mx defaults to 1, es is only 0.8)

David V.  
(That’s by far the ugliest code I’ve written in a year.)
