2010-03-10 3 views
2

숫자를 구문 분석해야하는 * nix "hostname"명령으로 채워지는 문자열이 있습니다. 그것은 쉬운 부분입니다. 어려움은 포착 된 숫자에 수학 (수학)을해야 할 필요성에서옵니다. 분명히 정규식 캡처는 항상 'add'또는 'modulo'와 같은 수학 함수가 없으며 '.to_i'에 대한 메소드도 가지고 있지 않은 MatchData 유형입니다. 현재 캡처 한 숫자에 대해 수학 (tm)을 수행하려면 MatchData의 .to_s 메서드를 사용하여 캡처를 문자열로 변환 한 다음 String의 .to_i를 사용하여 정수로 만들어야합니다. 내 질문은, 이것을하는 더 좋은 방법은 무엇입니까?루비 정규식 MatchData 대 정수 변환

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

귀하의 코드는 귀하가 말하는 것을하지 않았습니다. number == 웹 서버가 아님 1337 – shingara

+0

정말로 'temp1'이 필요하지 않습니다 :'number = number.to_s.to_i'이면 충분합니다. –

+0

Mark, 정확히 내가 뭘 찾고 있었는지 (물론, MatchData에 대한 .to_i 메쏘드가 존재할 것이지만 클래스를 패치하는 것은 ...이 스크립트에서 무거워진다.) 정말 고마워! –

답변

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 
+0

그게 저에게는 효과가 없었지만 숫자는 (hostname.match/\ d+ /)와 비슷했습니다. [0] .to_i +1 –

1

정규 표현식의 모든 데이터 추출은 문자열에서 추출되므로 문자열처럼 정의됩니다. 당신은


"webserver1337.mycorp.com" =~ /(\d+)/ 
p $1 #=> "1337" 
puts $1.class #=> String 
3

호스트 이름 = "webserver1337.mycorp.com"

번호 = 호스트 [/ \의 D + /] to_i + 1

+1

'number = hostname [/ \ d + /]. to_i + 1 rescue nil' – clyfe

+0

사실, String :: [regex] throw하지 않습니다; 일치하지 않으면 nil을 반환합니다. 그리고 nil.to_i는 0입니다. 구조가 잡을 수있는 유일한 것은 hostname이 nil (또는 string이 아닌 다른 것) 일 때뿐입니다. – jeem

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

나는 긍정적 인 성냥 대신에 부정적인 성냥으로 짧을 수 있다고 생각하지만, 이것은 나를 위해 끝내야 해!