Ruby регулярное выражение MatchData в целочисленное преобразование - PullRequest
2 голосов
/ 10 марта 2010

У меня есть строка, заполненная командой * nix "hostname", которую мне нужно проанализировать для числа. Это легкая часть. Трудность возникает из-за необходимости делать математику (tm) на этом захваченном числе. По-видимому, захваты регулярных выражений всегда имеют тип MatchData, который не имеет математических функций, таких как «add» или «modulo», и не имеет метода для «.to_i». В настоящее время, чтобы сделать Math (tm) для моего захваченного числа, мне нужно использовать метод MatchData .to_s, чтобы преобразовать перехват в строку, а затем использовать .to_i String, чтобы сделать его целым числом. У меня вопрос, как лучше это сделать?

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 ]

7 голосов
/ 10 марта 2010

Объект 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
3 голосов
/ 10 марта 2010

hostname = "webserver1337.mycorp.com"

число = имя хоста [/ \ d + /]. To_i + 1

1 голос
/ 10 марта 2010

Все данные, извлеченные из регулярного выражения, определяются как строка, поскольку они извлекаются из строки. Даже если вы извлекаете данные в явном виде


"webserver1337.mycorp.com" =~ /(\d+)/
p $1 #=> "1337"
puts $1.class #=> String
0 голосов
/ 22 февраля 2014

Верхнее совпадение не будет обрабатывать имя хоста с номером в середине. то есть 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

Я полагаю, что с отрицательным совпадением может быть короче, чем с положительным, но, похоже, это было сделано для меня!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...