【问题标题】:And/Or operator is ruby?和/或运算符是红宝石?
【发布时间】:2014-12-11 23:08:58
【问题描述】:

我有一个关于 Ruby 语法的快速问题: 我正在尝试编写一个程序,它需要一个字符串并用不同的子字符串替换子字符串,如果它包含初始子字符串。这是我的代码:

print "Thtring, pleathe!"

user_input = gets.chomp

if user_input.include? "s" || "S" || "cy" || "ce" || "ci"

    user_input.gsub!(/s/, "th")
    user_input.gsub!(/S/, "Th") 
    user_input.gsub!(/cy/, "th") 
    user_input.gsub!(/ce/, "th") 
    user_input.gsub!(/ci/, "th") 
else

    puts "No 's' found!"
end

puts "#{user_input}!" 

这工作正常,直到我有一个不包含“s”的句子。然后它只打印原始字符串而不做任何更改。 Ruby 中是否存在表示 AND/OR 的逻辑运算符?将所有 OR (||) 替换为。如果没有,我将如何重写它以使其工作?

【问题讨论】:

  • 你们太棒了!谢谢!

标签: ruby


【解决方案1】:

你现在做的很有效

if user_input.include?("s") || "S" || "cy" || "ce" || "ci"

(请注意添加的括号。)此外,您不能在 Ruby 中执行类似的操作 - || 运算符仅适用于布尔表达式。

你有两种选择:

if user_input.include?("s") || user_input.include?("S") || user_input.include?("cy") || user_input.include?("ce") || user_input.include?("ci")

或者更整洁的

if user_input =~ /s|S|cy|ce|ci/

【讨论】:

  • 或更短的/s|S|c[yei]/
【解决方案2】:

只是:

print "Thtring, pleathe!"
user_input = gets.chomp

puts "No 's' found!" unless user_input.gsub!(/s|S|cy|ce|ci/, 'th')

puts "#{user_input}!"

什么有效,因为如果没有替换任何内容,gsub! 将返回 nil

【讨论】:

    【解决方案3】:

    gsub 可以使用正则表达式模式和哈希实现一些看似鲜为人知的魔法。

    从要找到的目标字符串的哈希值及其替换开始:

    substitutions = {
      's' => "th",
      'S' => "Th",
      'cy' => "th",
      'ce' => "th",
      'ci' => "th",
    }
    

    我们可以根据键(目标字符串)构建正则表达式:

    substitution_pattern = Regexp.union(substitutions.keys) # => /s|S|cy|ce|ci/
    

    并将模式和哈希传递给gsub

    'String please!'.gsub(substitution_pattern, substitutions) # => "Thtring pleathe!"
    

    以下是个别测试:

    's'.gsub(substitution_pattern, substitutions) # => "th"
    'S'.gsub(substitution_pattern, substitutions) # => "Th"
    'cy'.gsub(substitution_pattern, substitutions) # => "th"
    'ce'.gsub(substitution_pattern, substitutions) # => "th"
    'ci'.gsub(substitution_pattern, substitutions) # => "th"
    

    Regexp.union 构建的模式并不是特别好,因为它真正做的只是join('|')。我们可以轻松创建更智能的模式:

    substitution_pattern = /[Ss]|c[eiy]/
    'String please!'.gsub(substitution_pattern, substitutions) # => "Thtring pleathe!"
    

    在 Stack Overflow 上有几个答案,我使用名为 Regexp::Assemble 的 Perl 模块为此目的生成非常复杂的模式。查看这些Regexp::Assemble answers 了解更多信息。特别是,“Is there an efficient way to perform hundreds of text substitutions in Ruby?”将向您展示执行此操作所需的所有知识。

    【讨论】:

    • 这个很金黄。虽然我在这里支持鲜为人知的方面。我个人从未见过这个,但回想起来并检查文档,你会认为它会更受欢迎
    • 这是进入 Ruby 内部一些更深层次的魔法。我发现很多开发人员往往不想深入研究语言并且满足于表面的东西,但语言的真正力量并不在表面上。使用适当的键集或构造良好的正则表达式模式,这可以将大量处理卸载到正则表达式引擎并将查找到哈希中,这两者都可以非常快。
    【解决方案4】:

    我猜你的操作符绑定优先级有问题。将 OR (||) 括在括号 (include?('s') || include?('S')) 中应该可以解决问题,并使您的代码正常工作。

    你也可以写成正则表达式:

    if user_input =~ /s|S|cy|ce|ci/
      user_input.gsub!(/s/, "th")
      user_input.gsub!(/S/, "Th") 
      user_input.gsub!(/cy/, "th") 
      user_input.gsub!(/ce/, "th") 
      user_input.gsub!(/ci/, "th")
    else
      puts "No 's' found!"
    end
    

    【讨论】:

      【解决方案5】:

      一个简单的方法是使用正则表达式。你可以这样做

      if user_input.match(/(s|S|cy|ce|ci)/)
        ...
      else
        ...
      end
      

      与往常一样,还有其他选择,例如 Milan Vladimirovic 的回答:

      if user_input =~ /(s|S|cy|ce|ci)/
      

      还有铁皮人的建议

      if user_input[/(s|S|cy|ce|ci)/]
      

      使用您喜欢的任何一种,因为它们在这种情况下功能上是等效的。另一件事是无论如何你都可以运行gsubs,因为它们不会改变任何不存在的东西,除非你真的想输出"No 's' found!"

      【讨论】:

      • 改用user_input[/s|S|c[yei]/]
      • 不错的一个!我实际上忘记了你可以做到这一点。通常,如果它们读得很好,我会选择措辞,尽管这个非常干净简洁
      猜你喜欢
      • 2011-08-12
      • 1970-01-01
      • 2011-02-28
      • 1970-01-01
      • 2013-08-14
      • 1970-01-01
      • 1970-01-01
      • 2011-04-28
      • 2014-08-06
      相关资源
      最近更新 更多