【问题标题】:How to replace a string and conserve capitalisation?如何替换字符串并节省大写?
【发布时间】:2017-01-12 05:19:07
【问题描述】:

使用 Ruby,是否可以替换字符串并节省大写。

想法是匹配“good day”并将其变成“holler”并保留原始大写。示例:

之前:

Good day to you sir and lady.
Hello and good day.

之后:

Holler to you sir and lady.
Hello and holler.

【问题讨论】:

  • 刚刚更新了问题以表明我需要完全替换,而不是追加。
  • 更新了我的答案以匹配您的新问题
  • @AnApprentice - 通过保留您对字符串的含义,例如:Hi, Good day to you sir and lady. 您想要的更改应该是:Hi, Holler to you sir and lady.??
  • 请查看我更新的答案,希望对您有所帮助。

标签: ruby-on-rails ruby regex gsub


【解决方案1】:

如果您打算保留部分字符串并附加到它,请使用反向引用和不区分大小写的搜索模式

yourstring.gsub(/(good day)/i, "\\1 and good night")

您可以在ruby rubular 中找到有关正则表达式如何工作的说明

更新

因为,正如您在评论和更新后的问题中所说,您希望替换的第一个字母是否大写,根据模式,我认为这种稍微冗长但有效的gsub 方法可以帮助您:

string = "Good day to you sir and lady. \nHello and good day."
puts string.gsub(/[gG]ood day/, 'good day' =>'holler', 'Good day'=>'Holler')
# Holler to you sir and lady.
# Hello and holler.

根据ruby 1.8.7gsub 可以接受散列作为第二个参数,并替换模式描述的可能匹配项。因此,上述语法等价于:

puts string.gsub(/[gG]ood day/, {'good day' =>'holler', 'Good day'=>'Holler'})

【讨论】:

  • 这只是一个例子,我希望完全替换而不是附加。
  • 那么,你想让句子的第一个字母大写吗?或者如果模式的第一个字母是大写,替换的第一个字母应该是大写?
  • 模式的第一个字母不是句子的第一个字母
【解决方案2】:

您可以将一个块传递给gsub,然后您可以操作匹配的字符串

并且传递的选项 i 将使正则表达式不区分大小写

string = "Good day to you sir and lady."

string.gsub(/good day/i) { |m| "#{m} and good night" }

#=> "Good day and good night to you sir and lady."

string = "Hello and good day."

string.gsub(/good day/i) { |m| "#{m} and good night" }

#=> "Hello and good day and good night."

参考gsub

【讨论】:

    【解决方案3】:

    你可以使用 Regexp 转义方法和忽略大小写选项来做这样的事情:

    reg = Regexp.new(Regexp.escape("good day"), Regexp::IGNORECASE)

    "good day".gsub(reg){|match| "#{match} and good night" }
    => "good day and good night"
    
    
    "Good dAy".gsub(reg){|match| "#{match} and good night" }
    => "Good dAy and good night"
    

    编辑以匹配更新的问题

    使用与原始问题的答案类似的想法

    "Good day".gsub(reg){|match| "#{match.capitalize == match ? 'Holler' : 'holler'} and good night" }
    => "Holler and good night"
    
    "good day".gsub(reg){|match| "#{match.capitalize == match ? 'Holler' : 'holler'} and good night" }
    => "holler and good night"
    

    【讨论】:

      【解决方案4】:

      这个方法:

      • text 中对old_str 应用不区分大小写的搜索
      • 对于每个找到的old_str
        • 它并行迭代 new_strold_str 字符
        • 它在new_str 上应用old_str 大小写

      def case_aware_replace(text, old_str, new_str)
        text.gsub(/#{old_str}/i) do |word|
          new_str.chars.zip(word.chars).map do |new_char, old_char|
            if old_char
              old_char.downcase == old_char ? new_char : new_char.upcase
            else
              new_char
            end
          end.join
        end
      end
      
      puts case_aware_replace('Good day to you sir and lady.', 'good day', 'holler')
      #=> Holler to you sir and lady.
      
      puts case_aware_replace('Hello and good day.', 'good day', 'holler')
      #=> Hello and holler.
      
      puts case_aware_replace('HELLO GRANDMA!', 'hello', 'hi')
      #=> HI GRANDMA!
      
      puts case_aware_replace('AaAaAaA', 'a', 'b')
      #=> BbBbBbB
      
      puts case_aware_replace('AaAaAaA', 'a', 'b ')
      #=> B b B b B b B
      
      puts case_aware_replace(case_aware_replace(case_aware_replace('IBM', 'i', 'international '),'b', 'business '),'m', 'machines ')
      #=> International Business Machines
      

      【讨论】:

        【解决方案5】:

        肯定会有更优雅的解决方案,但这也有帮助。

        2.3.1 :003 > a = "Good day to you sir and lady".downcase.gsub('good day', 'good day and good night').capitalize
         => "Good day and good night to you sir and lady" 
        

        我所做的是,

        • 将所有字母改为小写,
        • 替换了相关部分,
        • 然后大写。

        【讨论】:

        • 这不适用于他的问题的第二行,他不想每次都大写,他想保护原始大写,这意味着如果字符串中的good day没有大写,它应该如他示例的第二行所述,结果中不大写
        【解决方案6】:
        a = 'Good day to you sir and lady.
        Hello and good day.'
        
        a.gsub!('Good day', 'Hellor').gsub!('good day', 'hellor')
        

        会返回

        Hellor to you sir and lady.                                                                                                                                                                             
        Hello and hellor.   
        

        只有两种情况(假设只有首字母可以大写),直接替换两种情况就足够了。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-25
          • 2011-03-12
          • 1970-01-01
          • 1970-01-01
          • 2021-07-14
          • 1970-01-01
          • 2016-12-11
          • 2022-01-07
          相关资源
          最近更新 更多