我有一个字符串,从* nix“hostname”命令填充,我需要解析一个数字。这很容易。困难来自于需要对捕获的数字进行数学运算(tm)。显然,正则表达式捕获始终是MatchData类型,它没有任何数学函数,如“add”或“modulo”,也没有“.to_i”方法。目前,为了对我捕获的数字执行Math(tm),我需要使用MatchData的.to_s方法将捕获转换为字符串,然后使用String的.to_i使其成为整数。我的问题是,有什么更好的方法呢?
hostname = "webserver1337.mycorp.com"
number = hostname.match(/[a-z]+/)
puts "#{number}, with class #{number.class}" # prints '1337, with class MatchData'
somevar = number + 1 # this will fail horribly
temp1 = number.to_s
number = temp1.to_i
someothervar = number + 1
puts "#{number}, #{someothervar} with class #{number.class}" # prints '1337, 1338 with class FixNum'
这......有点难看。是否有更好/更清洁的方法来实现同样的目标?
答案 0 :(得分:6)
MatchData
对象将使用[]
返回匹配中包含的字符串。例如:
hostname = "webserver1337.mycorp.com"
m = hostname.match( /([a-z]+)(\d+)/ )
number = m[2].to_i + 1
p m[0], m[1], m[2], number
要做到这一点:
number = hostname.match(/\d+/)[0].to_i + 1
答案 1 :(得分:3)
hostname =“webserver1337.mycorp.com”
number = hostname [/ \ d + /] .to_i + 1
答案 2 :(得分:1)
正则表达式中的所有数据提取都定义为字符串,因为它是从字符串中提取的。即使你明确提取数字数据
"webserver1337.mycorp.com" =~ /(\d+)/
p $1 #=> "1337"
puts $1.class #=> String
答案 3 :(得分:0)
顶部匹配不会处理中间带有数字的主机名。即 foo23bar03或32bar30的编号错误。
类似于将数字匹配锚定到单词边界并可靠地获取数字:
number = hostname.match(/(\d+\b)/)[0]
在此基础上我做了:
#!/bin/env ruby
# simple test of hostname parser
class Hostname
attr_reader :name, :number, :full_name
def initialize(hostname)
parse = hostname.match(/([A-Za-z0-9\-\_]+[A-Za-z\-\_]+)(\d+\b)/).to_a || []
@full_name = parse.fetch(0, hostname)
@name = parse.fetch(1, hostname)
@number = parse.fetch(2, hostname).to_i
end
end
我为它编写了规范,并在这个要点上输出: https://gist.github.com/spheromak/9147685
我相信可以通过负面匹配而不是积极匹配来缩短,但这似乎可以让我完成它!