如何替换字符串并保留大写?

How to replace a string and conserve capitalisation?

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

想法是匹配"good day"并将其变成"holler"并保留原来的大小写。示例:

之前:

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

之后:

Holler to you sir and lady.
Hello and holler.

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

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" 

我所做的是,

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

如果您打算保留部分字符串并附加到它,请使用反向引用和case-insensitive 搜索模式

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

您可以在 rubular

中找到有关正则表达式如何在 ruby 中工作的解释

更新

因为,正如您在评论和更新的问题中所述,根据模式,您希望替换的首字母大写或不大写,我认为这种稍微冗长但有效的方法 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'})

您可以使用带有忽略大小写选项的 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"

您可以将一个块传递给 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

a = 'Good day to you sir and lady.
Hello and good day.'

a.gsub!('Good day', 'Hellor').gsub!('good day', 'hellor')

会return

Hellor to you sir and lady.                                                                                                                                                                             
Hello and hellor.   

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

这个方法:

  • text
  • 中应用 case-insensitive 搜索 old_str
  • 对于每个 old_str 找到:
    • 它并行迭代 new_strold_str 个字符
    • 它将 old_str 案例应用于 new_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