【问题标题】:Capitalize every nth character of each word in a string in Ruby将Ruby中字符串中每个单词的第n个字符大写
【发布时间】:2018-08-05 19:01:30
【问题描述】:

我需要将字符串中每个单词的每个“第 n 个”字符大写(在本例中为第 4 个字符的每个倍数,因此字符 4、8、12 等)。

我想出了下面的代码(我知道不是很优雅!)但它只适用于 length < 8 的单词。

'capitalize every fourth character in this string'.split(' ').map do |word|
  word.split('').map.with_index do |l,idx|
  idx % 3 == 0 && idx > 0 ? word[idx].upcase : l 
  end 
  .join('')
end 
.flatten.join(' ')

任何人都可以告诉我如何在长度 > 8 的单词中将每 4 个字符大写?

谢谢!

【问题讨论】:

    标签: ruby string uppercase


    【解决方案1】:
    def capitalize_each_nth_char(str, n)
      str.chars.each_slice(n).to_a.each { |arr| arr[-1] = arr[-1].upcase if arr.size == n }.join('')
    end
    

    这里是解释,

    str.chars # will give array of characters 
    
    str.chars.each_slice(n) # will give an enumerator as, #<Enumerator: ...> 
    
    str.chars.each_slice(n).to_a # will give an array of arrays 
    
    arr[-1].upcase # it will capitalize the last element i.e. 4th element of each array
    
    if arr.size == n # it will prevent to capitalize last element of sub-array if it's size is less than n(in our case 4)
    
    str.chars.each_slice(n).to_a.each { |arr| arr[-1] = arr[-1].upcase if arr.size == n } # it will give array of subarray where every subarray last element is capital
    
    str.chars.each_slice(n).to_a.each { |arr| arr[-1] = arr[-1].upcase if arr.size == n }.join('') # it will give the final result as, "capItalIze EverY foUrth chaRactEr iN thIs sTrinG"
    

    【讨论】:

      【解决方案2】:
      str = 'capitalize every fourth character in this string'
      
      idx = 0
      str.gsub(/./) do |c|
        case c
        when ' '
          idx = 0
          c
        else
          idx += 1
          (idx % 4).zero? ? c.upcase : c
        end
      end
        #=> "capItalIze eveRy fouRth chaRactEr in thiS strIng"
      

      【讨论】:

      • 不错的答案,我从未见过 .gsub() 以这种方式使用。
      • gsub 有很多技巧。假设您想匹配字符串str = "The numbers 350 and 450 are here"400500 之间的数字(如果存在)。你可以写str.gsub(/\d{3}/).find { |s| (400..500).cover?(s.to_i) } #=&gt; "450"
      【解决方案3】:

      作为一个选项,您可以通过索引访问字符来修改字符串中的第 n 个字符(如果存在):

      'capitalizinga every fourth character in this string'.split(' ').map do |word|
        (3..word.length).step(4) do |x|
          c = word[x]
          word[x] = c.upcase if c
        end
        word
      end.join(' ')
      
      # capItalIzinGa eveRy fouRth chaRactEr in thiS strIng
      

      这里使用了stepRange类的方法,因此可以计算每四个索引:3、7、11等...

      【讨论】:

        【解决方案4】:

        我认为最简单的方法是使用带有替换的正则表达式:

        'capitalize every fourth character in this string'
          .gsub(/([\w]{3})(\w)|([\w]{1,3})/) {
            "#{$1}#{$2.to_s.upcase}#{$3}"
          }
        
        # => capItalIze eveRy fouRth chaRactEr in thiS strIng
        

        这对捕获的组使用 2 个备选方案 - 第一个备选方案匹配 4 个字符,第二个备选方案匹配 1 到 3 个字符。 $1 组将精确匹配三个字母,$2 组将匹配 4 个字母块中的第四个字母 - 而 $3 组将匹配较长单词的剩余部分以及短于 4 个字符的单词。 然后,您可以用gsub 全局替换组$2。此外,如果$2nil,您还需要执行$2.to_s(或使用三元运算符捕捉这种情况)。

        您可以检查正则表达式here 并尝试代码here

        【讨论】:

        • 很好的答案,但为什么\w 必须在一个字符类中(两次)?
        • 感谢您的回答,我真的需要开始研究正则表达式超越 =~ /[a-z]/i :)
        【解决方案5】:
        > str.split(" ").map{|word| 
            word.chars.each_with_index{|c,i| 
              c.upcase! if (i > 0 && (i+1)%4 == 0)}.join}.join(" ")
        #=> "capItalIze eveRy fouRth chaRactEr in thiS strIng"
        

        【讨论】:

          猜你喜欢
          • 2010-12-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-24
          • 2010-10-16
          • 1970-01-01
          • 2014-06-19
          相关资源
          最近更新 更多