Ruby正则表达式匹配数据到整数转换

时间:2010-03-10 16:53:04

标签: ruby regex

我有一个字符串,从* 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'

这......有点难看。是否有更好/更清洁的方法来实现同样的目标?

4 个答案:

答案 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

我相信可以通过负面匹配而不是积极匹配来缩短,但这似乎可以让我完成它!