【问题标题】:Match capital letters and fill in with subsequent letters until certain string length匹配大写字母并填写后续字母,直到达到一定的字符串长度
【发布时间】:2016-04-29 15:49:09
【问题描述】:

我有一个驼峰式字符串,例如:JustAString

我想按照以下规则形成 长度为 4 的字符串:

  • 抓住所有大写字母;
  • 如果超过4个大写字母,只保留前4个;
  • 如果少于 4 个大写字母,则大写并在 最后一个大写字母之后添加字母,直到长度变为 4。

以下是可能发生的 3 种情况:

  • ThisIsMyString 将产生 TIMS(大写);
  • ThisIsOneVeryLongString 将产生 TIOV(前 4 个大写字母);
  • MyString 将产生 MSTR(大写字母 + tr 大写字母)。

我设法用这个 sn-p 解决了前两种情况:

str.scan(/[A-Z]/).first(4).join

但是,我不太确定如何最好地修改上述 sn-p 以处理最后一种情况(甚至尝试不同的方法)。

P.S.:保证字符串至少有一个大写字母和 4 个字符。但是,如果理论上缺少大写字母,则应考虑前 4 个字符。如果没有 4 个字符,可能会用第一个字母字符 (abcd) 填充缺失的字符。但是,如前所述,这两种极端情况通常不会发生。

【问题讨论】:

    标签: ruby regex string


    【解决方案1】:

    将大写字母前面的任何字符替换为空,然后获取前 4 个字符并大写:

    str.gsub(/[^A-Z]+([A-Z])/){$1}[0..3].upcase

    这也不处理大写字母。至于字符不足的边缘情况,您可以附加“abcd”,但我会发现在事后在单独的行中执行此操作更简洁:output_string = (output_string + "abcd")[0..3] if output_string.length < 4。如果这确实是一种罕见的边缘情况,那么它的读取会更清晰,并且性能(无关紧要)更好。

    【讨论】:

    • 很好,安德鲁。你也可以写str.gsub(/[^A-Z]+([A-Z])/,'\1')[0,4].upcase
    • 这确实很整洁!谢谢!
    【解决方案2】:

    这里有一个解决方案:

    ((str.scan(/[A-Z]/)[0..-2] + str.scan(/[A-Z][^A-Z]*$/)).join + "abcd")[0, 4].upcase
    

    这里是 cmets:

    (
      (
        str.scan(/[A-Z]/)[0..-2] + # All but the last capital letter
        str.scan(/[A-Z]?[^A-Z]*$/)  # The last capital letter, if any, plus trailing lowercase letters
      ).join +
      "abcd"
    )[0, 4]. # Take the first 4 chars, 4 capitals if we have them, then trailing lowercase if we have those, then the "abcd" filler
    upcase # upcase any trailing lowercase letters we included
    

    【讨论】:

    • 看起来很有趣。有没有办法使用单个正则表达式?我不确定如何编写“除最后一个之外的所有事件”正则表达式。
    • 您可以在单个正则表达式中匹配未知数量的可能被小写字母分隔的大写字母,但无法仅捕获大写字母。
    【解决方案3】:

    这里有两种方法。

    #1 使用带有正则表达式的String#gsub,后跟String#upcaseString#[]

    R = /
        [a-z]           # match a lower case letter
        (?=[a-z]*[A-Z]) # match >= 0 lower case letters followed by an upper case letter
                        # in a positive lookahead 
        /x              # free-spacing regex definition mode
    
    def get_caps(str, n)
      str.gsub(R,"").upcase[0,4]
    end
    
    get_caps("ThisIsMyString", 4)          #=> "TIMS"
    get_caps("ThisIsOneVeryLongString", 4) #=> "TIOV"
    get_caps("MyString", 4)                #=> "MSTR"
    get_caps("abcde", 4)                   #=> "ABCD"
    get_caps("", 4)                        #=> ""
    get_caps("AbcdefGh", 4)                #=> "AGH"
    

    #2 确定最后一个大写字母的索引,然后构建字符串

    def get_caps(str, n)
      idx = str.rindex(/[A-Z]/)
      return str[0,4].upcase if idx.nil?
      str.each_char.with_index.with_object('') { |(c,i),s|
        s << c.upcase if (s.size < n && (i > idx || c == c.upcase)) }
    end
    
    get_caps("ThisIsMyString", 4)          #=> "TIMS"
    get_caps("ThisIsOneVeryLongString", 4) #=> "TIOV"
    get_caps("MyString", 4)                #=> "MSTR"
    get_caps("abcde", 4)                   #=> "ABCD"
    get_caps("", 4)                        #=> ""
    get_caps("AbcdefGh", 4)                #=> "AGH"
    

    如果您希望在返回的字符串包含少于 n 字符的情况下返回 nil,请将该检查添加到方法中。

    【讨论】:

      猜你喜欢
      • 2021-01-06
      • 2019-08-08
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多