簡體   English   中英

Ruby Regex gsub! 不使用if

[英]Ruby Regex gsub! without using if

首先,要充分公開,我正在做作業。 我所舉的例子並不是確切的問題,但是可以幫助我理解我需要做的事情。 我不是在尋找答案,而是要了解發生了什么。

我正在嘗試采用如下字符串:

"The Civil War started in 1861."
"The American Revolution started in 1775."

在此示例中,我想返回相同的字符串,但是在后面加上適當的百分號

"The Civil War started in 1861. (Nineteenth Century)"
"The American Revolution started in 1775. (Eighteenth Century)"

我可以使用以下正則表達式將我需要的分組

text.gsub!(/([\w ]*)(1861|1775).?/, '\1\2 (NOT SURE HERE)')

使用分組來表示if \\2 == 1861附加了適當的世紀是很容易的,但是規范說if可以使用語句則不if並且我非常迷失。 另外,我在本示例中使用的替代方法僅適用於所列的兩年,並且我知道,與過去的兩年相比,必須使用更好的范圍匹配形式來捕獲整個世紀。

首先-如何刪除年份的硬編碼:

text.gsub!(/([\w ]*)([012]\d{3}).?/, '\1\2 (NOT SURE HERE)')

這應該可以處理接下來的大約1000年。 如果您知道日期僅限於給定期間,則可以更具體。


另一方面-世紀只是前兩位數字加一位。 因此,將年份一分為二並遞增。

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

請注意將String#gsub與block一起使用,因為我們需要對匹配的組之一執行轉換。


更新:如果您希望將百年歷史寫成文字,則可以使用數組來存儲它們。

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):假設您要替換完全不同的內容,並且無法利用像世紀示例中那樣的數字優點,實現相同的基本思想,僅使用哈希而不是數組:

replacements = {'cat' => 'king', 'mat' => 'throne'}

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

假設年份介於1到2099之間,則可以按以下方式進行操作。

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世紀”,那會更容易。

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)" 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM