rails - 使用RE从HTTP_ACCEPT_LANGUAGE中提取语言环境

时间:2014-02-05 09:23:21

标签: regex ruby-on-rails-3 rails-i18n

我使用RE从HTTP_ACCEPT_LANGUAGE中提取区域设置。 RailsGuides提供的推荐方式是:

request.env['HTTP_ACCEPT_LANGUAGE'].scan(/^[a-z]{2}/).first

不幸的是,在许多情况下,此RE不起作用,其中HTTP_ACCEPT_LANGUAGE类似于en-USzh-TWzh-CN。因此我修改了RE:

/^[\w\-\w]{2,5}/

这很有效。尽管如此,IDE还是给了我一个警告:character class has duplicated range: /^[\w\-\w]{2,5}/

如何避免此警告?

4 个答案:

答案 0 :(得分:1)

更好地使用下一个模式:

/^[a-z]{2}(-[A-Z]{2})?$/

但通常lang是en_US格式,_而不是-

答案 1 :(得分:1)

问题是,在方括号内,无论顺序如何,都列出了您要匹配的任何字符,因此[\w-\w][\w-]相同。将其更改为类似的内容应该可以实现您的目标:\w{2}(-\w{2})?

对于更严格的控制,您可以使用:^[a-z]{2}(-[A-Z]{2})?$

答案 2 :(得分:0)

从“正则表达式”的角度来看,@ npinti和@ Victor的答案很好。但是,当主题是“使用RE从rails中的HTTP_ACCEPT_LANGUAGE中提取区域设置”时,它们就不够用了。要在轨道中正确检测2个字符(例如“en”)和5个字符(例如“en-US”)格式:

# accept_language should be something like 
# "en-US,en;q=0.8,zh-TW;q=0.6,zh;q=0.4" (from chrome)
# however, it may be nil if the client doesn't set accept language in header.
accept_language = request.env['HTTP_ACCEPT_LANGUAGE'] || ""
# use "match" instead of "scan"!!
match_data = accept_language.match(/^[a-z]{2}(-[A-Z]{2})?/)
I18n.locale = match_data ? match_data[0] : I18n.default_locale

答案 3 :(得分:0)

为什么不只是.split(';', 2).first