0

我必须使用 String.scan 函数,如果没有匹配则返回空数组。

我想用扫描函数分配一个变量并检查它是否匹配,但不幸的是我不能这样做,因为它不会在不匹配时返回 nil 或 false 。

我想这样做(1行):

if ip = str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
  ...
  #use ip
end

但因为它不会在没有匹配的情况下返回 nil 我必须这样做:

ip_match = str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)
unless ip_match.empty?
  #use ip
end

有没有更优雅的方式来写这个——能够同时进行赋值和空检查,或者其他方式来美化代码?

谢谢

4

3 回答 3

2

由于 scan 返回一个数组,即使您确定只有一个结果,您也可以这样做。

str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/).each do |ip|
  #use ip
end
于 2012-09-05T07:03:07.880 回答
1

优雅和神秘或“简洁”之间是有区别的。

在 Perl 中,您经常会看到人们编写的内容相当于:

if (!(ip = str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)).empty?)

它更简洁、简洁、紧凑,随便你怎么称呼它。=由于(相等)与通常应该是相等测试的内容,它还会导致维护问题。如果将代码传递给不了解逻辑的人,他们可能会错误地“纠正”该代码,然后破坏代码。

在 Ruby 中,由于维护问题,在条件测试中不使用 equate 是惯用的,而是在测试之后使用赋值。这是更清晰的代码。

就个人而言,我不喜欢unless在那种情况下使用。是否unless有助于生成更易理解的代码,这是一个持续的讨论;我更喜欢if (!ip_match.empty?)它,因为它读起来更像我们通常谈话的内容——我很少unless在谈话中开始陈述。您的里程可能会有所不同。

于 2012-09-05T07:09:18.380 回答
1

String我最好使用助手做这样的事情match

ip_validator = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/

# match return nil if no match

if str.match ip_validator 
  # blah blah blah.....
end

帮助我保持代码干燥和清洁。可能这不是最优雅的,如果有的话寻找其他人:)

您的 ip_validator 正则表达式似乎是一周检查一下Rails 3: Validate IP String

于 2012-09-05T07:34:23.277 回答