ruby .gsub replace/substitute 特定范围的索引

ruby .gsub replace/substitute a specific range of indexes

Ruby 这里是新手。我正在尝试创建一种 'corrects' 电影片名的方法。这些方法应该正确地大写,忽略大写冠词 (a, an, the, of) 除非在开头,并且即使给定的标题全部大写或混乱也应该正确纠正。当我想在字符串 (1..100) 中指定一定范围的索引来查找文章并将它们更改为小写时,我遇到了困难。我的代码的前半部分运行得很好,但后半部分修改了一系列索引,.join 是我遇到问题的地方。如果可以在“.join”之后使用 .gsub 或 'if' 语句,这对于我的理解水平来说是最好的建议。我希望我是清楚的。任何 help/input 表示赞赏。谢谢

class Title
  attr_accessor :title
  def initialize(title)
    @title = title
  end

  def fix
    new_array = []
    @title.split.each do |word|
      new_array << "#{word}".capitalize
    end
    new_array.join(" ")
      new_array(1..100).gsub("Of","of").gsub("The","the").gsub("And","and")
    end
  end
end

或者:

class Title
  attr_accessor :title
  def initialize(title)
    @title = title
  end

  def fix
    new_array = []
    @title.split.each do |word|
      new_array << "#{word}".capitalize
    end
    new_array.join(" ")
    if new_array(1..100) then
      new_array.gsub("Of","of").gsub("The","the").gsub("And","and")
    end
  end
end

这是规格

describe "Title" do
  describe "fix" do
    it "capitalizes the first letter of each word" do
      expect( Title.new("the great gatsby").fix ).to eq("The Great Gatsby")
    end
    it "works for words with mixed cases" do
      expect( Title.new("liTTle reD Riding hOOD").fix ).to eq("Little Red Riding Hood")
    end
    it "downcases articles" do
      expect( Title.new("The lord of the rings").fix ).to eq("The Lord of the Rings")
      expect( Title.new("The sword And The stone").fix ).to eq("The Sword and the Stone")
      expect( Title.new("the portrait of a lady").fix ).to eq("The Portrait of a Lady")
    end
    it "works for strings with all uppercase characters" do
      expect( Title.new("THE SWORD AND THE STONE").fix ).to eq("The Sword and the Stone")
    end
  end
end

像这样使用 String#slice:

string[0..99]

用法示例:

string = "Everything"
string[5..8]
=> "thin"

Ruby 也有实现您目标的好方法:

stopwords = %w{ a an and but in of on or the }.to_set
title.capitalize.split.map{|word| 
  stopwords.include?(word) ? word : word.capitalize
}.join(" ")

这是解决您的问题的一种方法。我想提出一个可供考虑的替代方案。您正在寻求将标题中文章的任何实例大写,除非该实例位于标题的开头。您可以使用 .each_with_index 处理第二部分。对于第一部分,您可以创建一个目标单词数组,然后在目标数组中搜索单词,如下所示:

def fix
  articles = ["a", "and", "the", "of"]

  word_array = title.downcase.split(" ")
  new_array = []

  word_array.each_with_index do |word, index|
    if index == 0 || !articles.include?(word)
      new_array << word.capitalize
    else
      new_array << word
    end
  end
  new_array.join(" ")
end

所以 .downcase 将 "normalize" 你的标题,所以所有的单词都是小写的。 .split(" ") 会将您的字符串变成一个单词数组(在每个 space 处进行切割)。然后,您将使用 .each_with_index 访问该数组的每个元素。此方法使您可以访问元素和索引。然后你可以检查你是否在索引 0 或否定这个特定元素是否是一篇文章。 .includes? 检查传递给它的参数是否是调用它的数组的一个元素。它 returns truefalse 取决于它是否。在它前面加上 !,我们正在否定结果(将 true 变为 false,将 false 变为 true),因为我们只关心单词是否不在数组中。最后,我们调用 `.join(" ") 来传递一个字符串,如预期的那样用 space 分隔每个单词。