我必须使用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
是否有一些更优雅的方式来写这个 - 能够同时进行分配和空检查或其他方式美化代码?
由于
答案 0 :(得分:2)
由于扫描会返回一个数组,即使您确定只有一个结果,也可以这样做。
str.scan(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/).each do |ip|
#use ip
end
答案 1 :(得分: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
开始声明。您的里程可能会有所不同。
答案 2 :(得分: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