2016-07-29 4 views
1

У меня есть строка input = "2 + 3", которую я бы хотел конвертировать в "2.0 + 3.0". Я достиг этого с помощью следующих двух запутанных методов:Есть ли простой способ преобразования чисел в поплавки внутри строки?

floats = input.scan(/\d+/).map(&:to_f) 
operator = input.scan(/[+,\-,*,\/]/)  
operator.unshift(floats.first.to_s) 
     .push(floats.last.to_s).join(' ') 
#=> "2.0 + 3.0" 

или:

input.split(/\s+/) 
    .map{|i| ['+','-','*','/'].include?(i) ? i : i.to_f } 
    .join(' ') 
#=> "2.0 + 3.0" 

есть более простой и лучший способ сделать это?

+1

JFYI, этот стиль разбиения меток на несколько строк (точка сначала) IRB-недружественная. Это означает, что если вы вставляете этот код в IRB, вы получите кучу ошибок.Не исключено, что вы захотите вставить такой фрагмент в IRB. Поэтому используйте другой стиль ([точка последнего] (http://pastie.org/10922739)). –

+0

@ Сергио Туленцев благодарит вас за этот совет и за более раннее вмешательство. –

ответ

8

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

'1.0 + 2/4.5 - 15'.gsub(/(?<![\.\d])\d+(?![\.\d])/) { |m| "#{m}.0" } 
#⇒ "1.0 + 2.0/4.5 - 15.0" 
1

Регулярное выражение замены помогло бы здесь действительно:

floats = input.gsub(/(\d+)/, '\1.0') 

(\d+) захватывает любое число и помещает его в первой группе захвата. \1 возвращает первую группу захвата (то есть это число).

2

Вы можете попробовать это также

> "2 + 3".scan(/\d+/).map(&:to_f).join(" + ") 
=> "2.0 + 3.0" 

После консультации с @sergio я стараюсь делать это как GSUB также вдохновит выше @mudasobwa ответ ..

> "2 + 3/4.5".gsub(/(?<!\.)\b[0-9]+\b(?!\.)/) {|i| i.to_f} 
=> "2.0 + 3.0/4.5" 

также проверить

> "25 + 13/4.5".gsub(/(?<!\.)\b[0-9]+\b(?!\.)/) {|i| i.to_f} 
=> "25.0 + 13.0/4.5" 
+0

Я извиняюсь, что в моем вопросе не был ясен (хотя я надеялся, что это неявно из моих попыток), но код должен работать на входы с переменными операторами, то есть '" 2 - 3 "', '" 2 * 3 "', или '" 2/3 ". –

+1

@sag Затем попробуйте [мое предложение] (http://stackoverflow.com/questions/38651762/is-there-an-easy-way-to-convert-numbers-to-floats-within-a-string/38651799# 38651799), он работает для таких случаев. – nicael

+0

@ sagarpandya82 вы можете использовать оператор для объединения в качестве аргумента 's =" + "или s =" - "или s =" * "' then '" 2 + 3 ".scan (/ \ d + /). Map (& : to_f) .join (s) ' –

1

кодекса

def floatasize(str) 
    str.gsub(/\d+(?:\.\d+)?/) { |s| s.include?('.') ? s : "#{s}.0" } 
end 

Примеры

floatasize '1.0 + 2/4.5 - 15' 
    #=> "1.0 + 2.0/4.5 - 15.0" 
floatasize '-1 + 2/-4.5 - 15' 
    #=> "-1.0 + 2.0/-4.5 - 15.0" 
floatasize 'The expression is -1 + 2/-4.5 - 15.' 
    #=> "The expression is -1.0 + 2.0/-4.5 - 15." 

Разъяснение

Регулярное выражение читает ", соответствует одной или нескольким цифрам, а затем десятичной точкой, а затем одной или более цифрами". Обратите внимание, что в последнем примере регулярное выражение соответствует "15", а не "15.".

Блок может быть альтернативно записано

{ |s| "#{s}.0".to_f.to_s } 

Если gsub проходит "15" к блоку (s #=> "15"),

"#{"15"}.0".to_f.to_s 
    #=> "15.0".to_f.to_s 
    #=> 15.0.to_s 
    #=> "15.0" 

Если gsub проходит "4.5" к блоку (s #=> "4.5"),

"#{"4.5"}.0".to_f.to_s 
    #=> "4.5.0".to_f.to_s 
    #=> 4.5.to_s 
    #=> "4.5" 
+0

Это превосходно, как обычно, спасибо за объяснение. Немного опечатки в объяснении: _ блоку ('s # =>" 15 "') _ следует читать _... ('s # =>" 15.0 "') _ –

+0

sagar, я считаю 's # = > «15» 'правильно. В строке для регулярного выражения нет '' 15.0 "'. –

+0

ах gotcha, мое недоразумение. –

Смежные вопросы