在Ruby

时间:2016-07-31 22:33:24

标签: ruby

我正在尝试编写一段代码,用于删除字符串中的第一个和最后一个字符。字符需要用空格分隔,而不是用给定的逗号分隔。例如(“1,2,3,4”)将更改为(“2 3”)。

我坚持的一点是 - 如果我删除了第一个和最后一个字符,并且字符串现在为空,则它应该返回nil,例如(“1,2”)将是nil

到目前为止,我有:

def array(string)
 if string == ""
  return nil
 else 
  string.gsub!(',',' ')
  string.split
  string[2..-3]
 end
end

有人可以解释我哪里出错吗?

3 个答案:

答案 0 :(得分:3)

这是您的代码的固定版本:

def array(string)
  string.gsub!(',',' ')
  split = string.split
  trimmed = split[1..-2].join(' ')
  if trimmed == ""
    return nil
  else
    return trimmed
  end
end

p array('1, 2, 3, 4') # "2 3"
p array('2, 3') # nil

您的代码存在一些问题:

  1. 您正在检查函数的 start 中的空字符串,而不是在修剪它之后。 (因此,如果您完全传递了nil,它只会返回""。)
  2. 你没有存储你所做事情的结果。 string.split并未更改string的值。它返回一个数组,它是拆分字符串的结果。所以你需要将结果存储在一个数组中。 (例如split = string.split。)string.gsub!(...)是不同的。感叹号表示它是破坏性操作。它实际上改变了字符串。
  3. 你的指数在你的最终修剪上是错误的,但这可能是因为拆分实际上没有用,所以你试着调整索引。
  4. 你从来没有用空格加入结果。
  5. 这是您试用的另一个版本:

    def trim(string)
      trimmed = string.split(', ')[1..-2].join(' ')
      trimmed.empty? ? nil : trimmed
    end
    

    修改

    我刚刚想到你的索引可能是正确的,而你根本没打算实际拆分......这是代码的另一个工作版本:

    def array(string)
      string.gsub!(',', '') # NOTE: '' rather than ' '
      trimmed = string[2..-3]
      if trimmed == ""
        return nil
      else
        return trimmed
      end
    end
    

    请注意,此版本的代码依赖于以逗号分隔的值,只有一个字符长。如果您通过'12, 35, 421',它将无法工作。因此,我坚持基于split的方法。

答案 1 :(得分:0)

我会将正则表达式与方法String#countString#[]String#tr结合使用。

R = /
    \A            # match start of string
    .+?,\s+       # match >= 1 characters lazily (`?`) follow by a comma and >= 1 spaces
    \K            # forget everything matched so far
    .+            # match >= 1 characters greedily
    (?=,\s+\S+\z) # match a comma, >= 1 spaces, >= 1 characters other than
                  # sapces and end of string in a positive lookahead
    /x            # free-spacing regex definition mode

def doit(str)
   str.count(',') <= 1 ? nil : str[R].tr(',', ' ')
end

doit "11, 12, 13, 14"
  #=> "12  13"

doit "1, 4"
  #=> nil

doit "1"
  #=> nil

doit ""
  #=> nil

步骤如下。

str = "11, 12, 13, 14" 
str.count(',') <= 1
  #=> false
s = str[R]
  #=> "12, 13" 
s.tr(',', ' ')
  #=> "12  13" 

str = "1, 4"
str.count(',') <= 1
  #=> true
nil

这个正则表达式通常会写成

/\A.+?,\s+\K.+(?=,\s+\S+\z)/

您也可以在正则表达式中使用捕获组而不是两个外观:

R = /
   \A      # match start of string
   .+?,\s+ # match >= 1 characters lazily (`?`), a comma and >= 1 spaces
   (.+)    # match one or more characters (greedily) in capture group 1
   ,\s+\S+ # match a comma, >= 1 spaces, >= 1 characters other than spaces
   \z      # match end of string
   /x      # free-spacing regex definition mode

然后

def doit(str)
  str.count(',') <= 1 ? nil : str[R,1].tr(',', ' ')
end

通常可以选择。我更喜欢外观或\K,但这是个人偏好。

答案 2 :(得分:0)

def doit(str)
  return nil if str.count(',') <= 1
  str[(str.index(',')+1)...str.rindex(',')].lstrip.tr(',', ' ')
end

String#rindex用于查找字符串中最后一个逗号的索引。范围定义为三个点以排除最后一个逗号。

doit "1, 2, 3, 4" #=> "2  3"
doit "11, 12, 13" #=> "12"
doit "1, 4"       #=> nil
doit "1"          #=> nil
doit ""           #=> nil