4

I am implementing a multilang web service based on Accept-Language header. I use next code for parsing header and getting the requested language:

var matcher = language.NewMatcher([]language.Tag{
    language.English,
    language.Russian,
})
header:="ru, RUS, ru-RU, ru-ru"
tags, q, err := language.ParseAcceptLanguage(header)
for key, tag := range tags {
        matched, _, c := matcher.Match(tag)
        fmt.Printf("%s=>%f Matched as: %s (confidence: %s)\n", tag, q[key], matched, c)
    }

And results I get is

ru=>1.000000 Matched as: ru (confidence: Exact)
ru=>1.000000 Matched as: ru (confidence: Exact)
ru-RU=>1.000000 Matched as: ru-u-rg-ruzzzz (confidence: Exact)
ru-RU=>1.000000 Matched as: ru-u-rg-ruzzzz (confidence: Exact)

Why is 'ru-RU' matched as strange tag 'ru-u-rg-ruzzzz'? How can I match 'ru-Ru' as 'ru'?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
skeeph
  • 462
  • 2
  • 6
  • 18

1 Answers1

1

You will need to add "ru-RU" when you create your matcher.

var matcher = language.NewMatcher([]language.Tag{
    language.English,
    language.MustParse("ru-RU"),
    language.Russian,
})

when you pass in a region and it's not in your matcher it defaults to ZZ and you hit this code in the language package.

    } else if r := w.RegionID.String(); len(r) == 2 {
        // TODO: also filter macro and deprecated.
        tt, _ = tt.SetTypeForKey("rg", strings.ToLower(r)+"zzzz")
    }

If you only want to get the language you can get use the Base method from the returned matched tag

matched, _, _ := matcher.Match(tag)
base, _ := matched.Base();
fmt.Println(base.String()) // will only print the language

using base.String() will print ru for all of the language headers you provided.

jmaloney
  • 11,580
  • 2
  • 36
  • 29