Як я можу перевірити, чи є значення числом?


82

Я хочу просто перевірити, чи повертається значення з текстового поля форми числом, тобто: 12, 12,5 або 12,75. Чи є простий спосіб перевірити це, особливо якщо значення витягується як a param?


гм, єдине, що код працює для is_a_number? працює з єдиним винятком .02, або .3 числа ....
user211662

7
Я набагато віддаю перевагу такому рішенню: stackoverflow.com/questions/5661466/... Я не знаю, чому так багато людей вважають, що регулярний вираз буде кращим для цього.
2called-chaos

Відповіді:


26

Просто регулярно викладіть це, це тривіально, і не варто думати над цим:

v =~ /\A[-+]?[0-9]*\.?[0-9]+\Z/

(Виправлено згідно з коментарем Джастіна)


5
У рубіні ^ і $ позначають початок / кінець рядка, а не рядка. Це робить його неефективним для використання як засіб для дезінфекції вхідних даних (див. Guides.rubyonrails.org/security.html#regular-expressions ). Краще було б: v.to_s =~ /\A[-+]?\d*\.?\d+\z/.
Джастін

208

Можна використовувати

12.is_a? Numeric

( Numericпрацюватиме для цілих чи значень з плаваючою точкою.)

Якщо він надходить у вигляді рядка, який може містити подання дійсного числа, ви можете використовувати

class String
  def valid_float?
    true if Float self rescue false
  end
end

а потім '12'.valid_float?поверне true, якщо ви зможете перетворити рядок у дійсний плаваючий символ (наприклад, за допомогою to_f).


На жаль, це Ruby on Rails ... В основному, я просто хочу мати можливість оцінити будь-який вхід від користувача, чи це буде .03 0,3, 2,2 Останні два працюють, але мені потрібно, щоб перший вхід працював: S
user211662

10
Fixnumсхоже, не працює з поплавками. Однак Numericпрацює нормально. Отже 1.234.is_a? Fixnum == false, але 1.234.is_a? Numeric == true.
KurtPreston

Це не працює з поплавками. Потрібно використовувати 1.1.is_a? NumericДив. Stackoverflow.com/a/17668654/76486
Брайан Армстронг

1
Не працює для мене :(pry(main)> '12'.is_a? Numeric => false
Саліл,

@Salil, очевидно, що у вас не вийде, '12'це рядок. У такому випадку перевірте рядок за допомогою Regex або будь-якого іншого можливого рішення.
edmundo096

27

Зазвичай я просто використовую Integer і Float в наші дні.

1.9.2p320 :001 > foo = "343"
 => "343"
1.9.2p320 :003 > goo = "fg5"
 => "fg5"

1.9.2p320 :002 > Integer(foo) rescue nil
 => 343
1.9.2p320 :004 > Integer(goo) rescue nil
 => nil

1.9.2p320 :005 > Float(foo) rescue nil
 => 343.0
1.9.2p320 :006 > Float(goo) rescue nil
 => nil


7

Просто перетворіть рядок двічі:

num = '12'
num == num.to_i.to_s 
#=> true 

num = '3re'
num == num.to_i.to_s 
#=> false

Працює не так погано з цілими числами, але існує так багато способів не вдатися, якщо ви хочете слідувати цій пораді з поплавками (саме про це запитує запитання): "7" == "7".to_f.to_s #=> false("7" проти "7.0")
Девід Стосік,

Ви можете це зробитиnum == num.to_i.to_s || num == num.to_f.to_s
mannykary

ви також можете відформатувати обидва рядки за допомогою оператора "%", щоб гарантувати, що вони обидва закінчуються одним рядком
Jaacko Torus

5

Я б запропонував цей

def is_number?
  self.to_f == self
end

> 15.is_number?
=> true
> 15.0.is_number?
=> true
> 'Not a number'.is_number?
=> false
> (0/0.0).is_number?
=> false

4
irb(main):005:0> 1.1.is_a? Numeric
=> true
irb(main):006:0> 1.is_a? Numeric
=> true
irb(main):007:0> 'asd'.is_a? Numeric
=> false

7
"1.1" .is_a? Числовий => помилковий
годинник

Як би ви вирішили проблему перетворення рядка? OP стверджує, що це з текстового поля.
Шлінгель

-5

Значення рядків завжди перетворюються на 0 за допомогою .to_i

[14] pry(main)> 'Apple'.to_i > 0
=> false

[15] pry(main)> '101'.to_i > 0
=> true

А як щодо крайових футлярів? Якщо число 0 або від’ємне, ваш тест дасть помилково негативний результат.
циков

Ще гірше '1AB2'.to_i поверне 1 за щось, що явно не є
цілим числом
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.