首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby Regex gsub!不使用if

Ruby Regex gsub!不使用if
EN

Stack Overflow用户
提问于 2016-05-01 00:58:52
回答 2查看 58关注 0票数 0

首先,完全公开,我正在做一项家庭作业。我给出的例子并不是确切的问题,但可以帮助我理解我需要做什么。我不是在寻找一个填鸭式的答案,而是想要理解发生了什么。

我正在尝试获取一个字符串,例如:

代码语言:javascript
复制
"The Civil War started in 1861."
"The American Revolution started in 1775."

在本例中,我想返回相同的字符串,但在后面加上适当的世纪

代码语言:javascript
复制
"The Civil War started in 1861. (Nineteenth Century)"
"The American Revolution started in 1775. (Eighteenth Century)"

我可以使用以下正则表达式对所需内容进行分组

代码语言:javascript
复制
text.gsub!(/([\w ]*)(1861|1775).?/, '\1\2 (NOT SURE HERE)')

使用grouping可以很容易地说if \2 == 1861附加适当的世纪,但是规范说不能使用if语句,我非常迷惑。此外,我在此示例中使用的交替仅适用于列出的两年,我知道必须使用更好的范围匹配形式来捕获完整的世纪,而不是这两个单独的年份。

EN

回答 2

Stack Overflow用户

发布于 2016-05-01 01:11:02

首先-如何删除年份的硬编码:

代码语言:javascript
复制
text.gsub!(/([\w ]*)([012]\d{3}).?/, '\1\2 (NOT SURE HERE)')

这应该可以在接下来的1000年内处理一些事情。如果您知道日期仅限于给定的时间段,则可以更具体。

另一方面,世纪是前两位数加一位数。因此,将这一年一分为二并递增。

代码语言:javascript
复制
text.gsub(/[\w ]*([012]\d)\d\d.?/) do |sentence|
  "#{sentence} (#{$1.next}th Century)"
end

注意String#gsub with block的用法,因为我们需要在一个匹配组上执行转换。

更新:如果你想用文字表示几个世纪,你可以使用一个数组来存储它们。

代码语言:javascript
复制
ordinals = %w(
  First Second Third Fourth Fifth Sixth Seventh Eighth Ninth Tenth Eleventh
  Twelfth Thirteenth Fourteenth Fifteenth Sixteenth Seventeenth Eighteenth
  Nineteenth Twentieth Twenty–First
)

text.gsub(/[\w ]*([012]\d)\d\d.?/) do |sentence|
  "#{sentence} (#{ordinals[$1.to_i]} Century)"
end

更新(2):假设你想要替换一些完全不同的东西,并且你不能像在世纪示例中那样利用数字细节,实现相同的一般思想,只需使用散列而不是数组:

代码语言:javascript
复制
replacements = {'cat' => 'king', 'mat' => 'throne'}

"The cat sat on the mat.".gsub(/^(\w+ )(\w+)([\w ]+ )(\w+)\.$/) do
  "#{$1}#{replacements[$2]}#{$3}#{replacements[$4]}."
end
票数 2
EN

Stack Overflow用户

发布于 2016-05-01 03:16:45

假设年份在1到2099年之间,您可能会这样做。

代码语言:javascript
复制
YEAR_TO_CENTURY = (1..21).to_a.zip(%w| First Second Third Fourth Fifth Sixth
  Seventh Eighth Ninth Tenth Eleventh Twelfth Thriteenth Fourteenth Fifteenth
  Sixteenth Seventeenth Eighteenth Nineteenth Twentieth Twentyfirst | ).to_h
  #=> { 1=>"First", 2=>"Second", 3=>"Third", 4=>"Fourth", 5=>"Fifth", 6=>"Sixth",
  #     7=>"Seventh", 8=>"Eighth", 9=>"Ninth", 10=>"Tenth", 11=>"Eleventh",
  #    12=>"Twelfth", 13=>"Thriteenth", 14=>"Fourteenth", 15=>"Fifteenth",
  #    16=>"Sixteenth", 17=>"Seventeenth", 18=>"Eighteenth", 19=>"Nineteenth",
  #    20=>"Twentieth", 21=>"Twentyfirst" }

def centuryize(str)
  str << " (%s Century)" % YEAR_TO_CENTURY[(str[/\d+(?=\.)/].to_i/100.0).ceil]
end

centuryize "The American Revolution started in 1775."
  #=> "The American Revolution started in 1775. (Eighteenth Century)" 
centuryize "The Battle of Hastings took place in 1066."
  #=> "The Battle of Hastings took place in 1066. (Eleventh Century)" 
centuryize "Nero played the fiddle while Rome burned in AD 64."
  #=> "Nero played the fiddle while Rome burned in AD 64. (First Century)"

如果我们能写下“19世纪”就更容易了。

代码语言:javascript
复制
def centuryize(str)
  century = (str[/\d+(?=\.)/].to_i/100.0).ceil
  suffix = 
  case century
  when 1, 21 then "st"
  when 2     then "nd"
  when 3     then "rd"
  else            "th"
  end
  "%s (%d%s Century)" % [str, century, suffix]
end

centuryize "The American Revolution started in 1775."
  # => "The American Revolution started in 1775. (18th Century)" 
centuryize "The Battle of Hastings took place in 1066."
  #=> "The Battle of Hastings took place in 1066. (11th Century)" 
centuryize "Nero played the fiddle while Rome burned in AD 64."
  #=> "Nero played the fiddle while Rome burned in AD 64. (1st Century)" 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36957661

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档