回答:
正規表現を使用できます。@janmが提案する関数を以下に示します。
class String
def is_i?
!!(self =~ /\A[-+]?[0-9]+\z/)
end
end
@wichからのコメントによる編集バージョン:
class String
def is_i?
/\A[-+]?\d+\z/ === self
end
end
正の数だけをチェックする必要がある場合
if !/\A\d+\z/.match(string_to_check)
#Is not a positive number
else
#Is all good ..continue
end
/regexp/ === self
代わりに使用できます!!(self =~ /regexp/)
。あなたは、文字クラス「\ D」の代わりに使用することができます[0-9]
さて、ここに簡単な方法があります:
class String
def is_integer?
self.to_i.to_s == self
end
end
>> "12".is_integer?
=> true
>> "blah".is_integer?
=> false
文字列を変換するために例外を引き起こすソリューションに同意しません-例外は制御フローではなく、あなたはそれを正しい方法で行うこともできます。とはいえ、上記の私の解決策は、基数10以外の整数を処理しません。だからここに例外に頼らずに行う方法があります:
class String
def integer?
[ # In descending order of likeliness:
/^[-+]?[1-9]([0-9]*)?$/, # decimal
/^0[0-7]+$/, # octal
/^0x[0-9A-Fa-f]+$/, # hexadecimal
/^0b[01]+$/ # binary
].each do |match_pattern|
return true if self =~ match_pattern
end
return false
end
end
self.to_i.to_s == self
られInteger self rescue false
ませんか?
あなたはInteger(str)
それが発生するかどうかを使用して見ることができます:
def is_num?(str)
!!Integer(str)
rescue ArgumentError, TypeError
false
end
これはに対してtrueを返しますが、有効な整数リテラル"01"
ではないため"09"
、に対してはtrueを返しません09
。それが10
目的の動作でない場合は、2番目の引数としてを追加できるInteger
ため、数値は常に10を底として解釈されます。
#to_i
許容性のため、使用するメソッドはあまりにも壊れています。
Integer()
ので、正規Integer ()
です。言語がすでにあなたに与えているものを複製することは、おそらく制御のために例外を使用するよりも悪いコード臭です。
あなたはワンライナーを行うことができます:
str = ...
int = Integer(str) rescue nil
if int
int.times {|i| p i}
end
あるいは
int = Integer(str) rescue false
何をしようとしているのかに応じて、レスキュー句付きの開始終了ブロックを直接使用することもできます。
begin
str = ...
i = Integer(str)
i.times do |j|
puts j
end
rescue ArgumentError
puts "Not an int, doing something else"
end
"12".match(/^(\d)+$/) # true
"1.2".match(/^(\d)+$/) # false
"dfs2".match(/^(\d)+$/) # false
"13422".match(/^(\d)+$/) # true
true
とfalse
なく、MatchData
インスタンスとnil
!!
、ラップするか使用しpresent?
ます!!( "12".match /^(\d)+$/ )
"12".match(/^(\d)+$/).present?
Ruby 2.6.0では、例外を発生させることなく整数へnil
のキャストが可能で、キャストが失敗すると戻ります。そして、nil
ほとんどがfalse
Rubyのように動作するため、次のように整数を簡単にチェックできます。
if Integer(my_var, exception: false)
# do something if my_var can be cast to an integer
end
class String
def integer?
Integer(self)
return true
rescue ArgumentError
return false
end
end
is_
。私は次のように、questionmark法上のそれは愚かな私を見つける"04".integer?
よりも良好たくさん"foo".is_integer?
。"01"
。integer?("a string")
ftl。
String#integer?
Rubyのすべてのコーダーとそのいとこが言語に追加することを好む種類の一般的なパッチであり、わずかに互換性のない3つの異なる実装と予期しない破損をコードベースにもたらします。大規模なRubyプロジェクトでこれを難しい方法で学びました。
最良でシンプルな方法は Float
val = Float "234" rescue nil
Float "234" rescue nil #=> 234.0
Float "abc" rescue nil #=> nil
Float "234abc" rescue nil #=> nil
Float nil rescue nil #=> nil
Float "" rescue nil #=> nil
Integer
また良いですがそれはの0
ために戻りますInteger nil
私は好む:
config / initializers / string.rb
class String
def number?
Integer(self).is_a?(Integer)
rescue ArgumentError, TypeError
false
end
end
その後:
[218] pry(main)> "123123123".number?
=> true
[220] pry(main)> "123 123 123".gsub(/ /, '').number?
=> true
[222] pry(main)> "123 123 123".number?
=> false
または電話番号を確認してください:
"+34 123 456 789 2".gsub(/ /, '').number?
より簡単な方法は
/(\D+)/.match('1221').nil? #=> true
/(\D+)/.match('1a221').nil? #=> false
/(\D+)/.match('01221').nil? #=> true
Ruby 2.4にはRegexp#match?
(:付き?
)
def integer?(str)
/\A[+-]?\d+\z/.match? str
end
古いRubyバージョンにはがありRegexp#===
ます。また、大文字と小文字の等値演算子を直接使用することは一般的に避けられるべきですが、ここでは非常にきれいに見えます。
def integer?(str)
/\A[+-]?\d+\z/ === str
end
integer? "123" # true
integer? "-123" # true
integer? "+123" # true
integer? "a123" # false
integer? "123b" # false
integer? "1\n2" # false
これが私の解決策です:
# /initializers/string.rb
class String
IntegerRegex = /^(\d)+$/
def integer?
!!self.match(IntegerRegex)
end
end
# any_model_or_controller.rb
'12345'.integer? # true
'asd34'.integer? # false
そして、それがどのように機能するかです:
/^(\d)+$/
ある正規表現任意の文字列に数字を見つけるための式は。正規表現と結果はhttp://rubular.com/でテストできます。IntegerRegex
メソッドで使用するたびに不必要なメモリ割り当てを回避するために、定数に保存します。integer?
返す必要があります疑問方法ですtrue
かfalse
。match
引数の指定された正規表現に従って出現と一致し、一致した値を返す文字列のメソッドです。または nil
です。!!
の結果を変換します match
メソッドを同等のブール値にます。String
クラスでメソッドを宣言することは、既存のString機能で何も変更せずinteger?
、任意のStringオブジェクトで指定された別のメソッドを追加するだけの、モンキーパッチです。上記の@radoの回答を拡張すると、3項ステートメントを使用して、ダブルバンを使用せずにtrueまたはfalseのブール値を強制的に返すこともできます。確かに、二重論理否定バージョンはより簡潔ですが、おそらく(私のような)初心者には読みにくいでしょう。
class String
def is_i?
self =~ /\A[-+]?[0-9]+\z/ ? true : false
end
end
より一般的なケース(小数点付きの数値を含む)の場合は、次の方法を試すことができます。
def number?(obj)
obj = obj.to_s unless obj.is_a? String
/\A[+-]?\d+(\.[\d]+)?\z/.match(obj)
end
このメソッドは、irbセッションでテストできます。
(irb)
>> number?(7)
=> #<MatchData "7" 1:nil>
>> !!number?(7)
=> true
>> number?(-Math::PI)
=> #<MatchData "-3.141592653589793" 1:".141592653589793">
>> !!number?(-Math::PI)
=> true
>> number?('hello world')
=> nil
>> !!number?('hello world')
=> false
obj.is_a? String
ため、呼び出す必要はありません。これは、呼び出しに比べてあまり多くの処理を必要としないと思います。この方法では、この行では1つまたは2つではなく1つだけ呼び出します。また、慣例により、で終わるメソッド名はブール値を返すことになっているため、メソッド内に直接含めることもできます。よろしく!.is_a?
!!
number?
?
この質問が出されたときにこれがあったかどうかはわかりませんが、この投稿を偶然見つけた人にとって、最も簡単な方法は次のとおりです。
var = "12"
var.is_a?(Integer) # returns false
var.is_a?(String) # returns true
var = 12
var.is_a?(Integer) # returns true
var.is_a?(String) # returns false
.is_a?
任意のオブジェクトで動作します。
"12".is_an_integer? == true
"not12".is_an_integer? == false
12.is_an_integer? == true