Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/54.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 从Ruby中的字符串中提取月份名称_Ruby On Rails_Ruby_Ruby On Rails 4 - Fatal编程技术网

Ruby on rails 从Ruby中的字符串中提取月份名称

Ruby on rails 从Ruby中的字符串中提取月份名称,ruby-on-rails,ruby,ruby-on-rails-4,Ruby On Rails,Ruby,Ruby On Rails 4,我正在使用RubyonRails应用程序。在我调用API的一个地方的应用程序中,从10月到11月,返回字符串为的API增加了4.35%。我的要求是,当我在用户界面上显示时,我需要将其显示为从10月到11月上涨4.35% 有人能告诉我怎么做吗 您可以为此使用gsub 只需将我的示例扩展到所有月份: "Up 4.35% from Oct to Nov".gsub(/Oct|Nov/) do |s| {'Oct' => 'October', 'Nov' => 'November'}[

我正在使用RubyonRails应用程序。在我调用API的一个地方的应用程序中,从10月到11月,返回字符串为
的API增加了4.35%
。我的要求是,当我在用户界面上显示时,我需要将其显示为从10月到11月上涨4.35%


有人能告诉我怎么做吗

您可以为此使用
gsub

只需将我的示例扩展到所有月份:

"Up 4.35% from Oct to Nov".gsub(/Oct|Nov/) do |s| 
  {'Oct' => 'October', 'Nov' => 'November'}[s]
end
# => "Up 4.35% from October to November" 
最后,只需调用函数:

replace(str)
String#sub
是您所需要的

试试这个:

a = "Up 4.35% from Oct to Nov"
a.sub('Oct', 'October').sub('Nov', 'November') # you can continue with other months
#=> "Up 4.35% from October to November"

Date::MONTHNAMES
可能会帮助您。如果月份总是3个字符的缩写版本,您可以构建一个哈希来帮助:

dates = Date::MONTHNAMES.compact.map { |m| [m[0..2], m] }.to_h
然后在其他地方使用它:

text = 'Up 4.35% from Oct to Nov'
text.gsub(/#{dates.keys.join('|')}/, dates)
=> "Up 4.35% from October to November"

人们不会注意到这个特殊的能力,所以请思考一下:

SHORT_TO_LONG_MONTH_NAMES = %w[
  January
  February
  March
  April
  May
  June
  July
  August
  September
  October
  November
  December
].map{ |m| [m[0, 3], m] }.to_h
# => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}

SHORT_TO_LONG_MONTH_NAMES_REGEX = /\b(?:#{ Regexp.union(SHORT_TO_LONG_MONTH_NAMES.keys).source })\b/
# => /\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\b/

str = 'Up 4.35% from Oct to Nov'

str.gsub(SHORT_TO_LONG_MONTH_NAMES_REGEX, SHORT_TO_LONG_MONTH_NAMES)
# => "Up 4.35% from October to November"
以非常简洁的方式剥离输出结果,以便在文档中快速搜索和替换:

SHORT_TO_LONG_MONTH_NAMES = %w[
  January
  February
  March
  April
  May
  June
  July
  August
  September
  October
  November
  December
].map{ |m| [m[0, 3], m] }.to_h

SHORT_TO_LONG_MONTH_NAMES_REGEX = /\b(?:#{ Regexp.union(SHORT_TO_LONG_MONTH_NAMES.keys).source })\b/

str = 'Up 4.35% from Oct to Nov'

str.gsub(SHORT_TO_LONG_MONTH_NAMES_REGEX, SHORT_TO_LONG_MONTH_NAMES)
# => "Up 4.35% from October to November"
旧红宝石没有
到_h
,因此您可以使用此选项:

SHORT_TO_LONG_MONTH_NAMES = Hash[%w[
  January
  February
  March
  April
  May
  June
  July
  August
  September
  October
  November
  December
].map{ |m| [m[0, 3], m] }]
# => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}
分解正则表达式模式生成:

SHORT_TO_LONG_MONTH_NAMES_REGEX = /\b(?:#{ Regexp.union(SHORT_TO_LONG_MONTH_NAMES.keys).source })\b/
  • \b
    是分词或分词,意思是一个词的开始或结束位置。“单词”是字符集
    [A-zA-Z0-9.]
    ,也称为
    \w
    ,分词是前一个非单词字符和单词字符之间的分界线。未能做到这一点是所有人类苦难的根源;替换字符串将在没有
    \b
    的情况下匹配,因此可以得到各种有趣的替换
  • (?:…)
    定义了一个非捕获组,这是找到一系列替代模式的好方法,在本例中,它是由三个字母缩写的月份名称组成的列表
  • 是一种有用的方法,它采用数组(在本例中为散列的键),并用模式中的OR符号
    |
    将它们分开。基本上,这意味着任何键都可以匹配
  • 这是其中非常重要的一部分。如果没有它,
    Regexp.union
    (一个已编译的正则表达式)的结果将被插入到字符串中,以及它的相关标志,这可能会导致搜索冲突。考虑这些之间的差异:

    /foo/i # => /foo/i
    /#{ /foo/i }/ # => /(?i-mx:foo)/
    /foo/i.source # => "foo"
    /#{ /foo/i.source }/ # => /foo/
    
    第一种是不区分大小写的模式。第二个是嵌入在区分大小写的模式中的不区分大小写的模式,但是
    (?i-mx:
    在内部将其标记为不区分大小写。这是一个等待中的错误,除非您确实确定这是您想要的

    source
    返回没有标记的模式的字符串化版本,因此最终结果是我们实际期望的结果

我以前也被它咬过,追踪它是一件非常痛苦的事情

最后,Date类有一些预定义的常量,这将允许您不必像我上面所做的那样长时间定义哈希。这是为了让发生的事情变得明显,但为了方便起见,您可以执行以下操作:

require 'date'

Date::ABBR_MONTHNAMES.zip(Date::MONTHNAMES)[1..-1].to_h # => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}
Hash[Date::ABBR_MONTHNAMES.zip(Date::MONTHNAMES)[1..-1]] # => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}

/\b(?:#{ Regexp.union(Date::ABBR_MONTHNAMES[1..-1]).source }\b)/ # => /\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec\b)/

注意
[1..-1]的用法
在示例中。这是因为数组的第一个值包含一个nil,使数组基于1,而不是基于0,这是为了我们的查找乐趣,但如果您试图使用数组作为模式,这会使Ruby嚎叫。

您可以将哈希作为
gsub
的第二个参数传递,不需要块:
'abc'(/a | b/,'a'=>'x','b'=>'y')#=>“xyc”
。日期::MONTHNAMES是个好主意,但我会将它与@toro2k对MikDiet答案的评论结合起来,以获得更好的解决方案。确实。更新后可以使用它们。在使用
日期.键时要非常小心。加入('.')
。“非常小心”是什么意思这是什么意思?请阅读我的答案,其中有解释。字符串格式是否始终具有示例中的月份?
require 'date'

Date::ABBR_MONTHNAMES.zip(Date::MONTHNAMES)[1..-1].to_h # => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}
Hash[Date::ABBR_MONTHNAMES.zip(Date::MONTHNAMES)[1..-1]] # => {"Jan"=>"January", "Feb"=>"February", "Mar"=>"March", "Apr"=>"April", "May"=>"May", "Jun"=>"June", "Jul"=>"July", "Aug"=>"August", "Sep"=>"September", "Oct"=>"October", "Nov"=>"November", "Dec"=>"December"}

/\b(?:#{ Regexp.union(Date::ABBR_MONTHNAMES[1..-1]).source }\b)/ # => /\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec\b)/