10

文字列の「数値」を検証したかった(アクティブレコードモデルの属性ではない)。有効な基数10の正の整数文字列である必要があります。私はこれをやっています:

class String
  def numeric?
    # Check if every character is a digit
    !!self.match(/\A[0-9]+\Z/)
  end
end

class String
  def numeric?
    # Check is there is *any* non-numeric character
    !self.match(/[^0-9]/)
  end
end

これらのうち、より妥当な代替案はどれですか?または、他にもっと良い実装はありますか?

4

8 に答える 8

10

文字列の1行だけでなく、文字列全体に一致させるには、必ず\Aand\Zではなく^andを使用してください。$文字列と末尾の改行が一致しないようにする場合は、末尾に「\z」を使用します。その他の問題については、アンカーに関する正規表現チュートリアルを参照してください。

たとえば/^[0-9]+$/、次のように正常に一致します。

foo
1234
bar

しかし、/\A[0-9]+\Z/そうではありません。

于 2009-08-17T23:38:05.857 に答える
5

最初のものは私には正気に見えます。

ただし、メソッドnumeric?に名前を付けます。私はis_foo?メソッドの大ファンではありません。is_fooメソッド名( 、 )に疑問符がない言語では意味がありますがisFoo、疑問符があるisと冗長な感じがします。

于 2009-08-17T09:17:40.837 に答える
3

私は100%確実ではありませんが、Railsは/\A[+-]?\d+\Z/整数に使用しているようです。こちら
のソースを表示をクリックしてくださいvalidates_numericality_of

于 2009-08-17T09:50:28.133 に答える
2

私はそれを行う別の方法を提案したいと思います。また、あなたが「正の」整数を尋ねたので、私は正の整数と非負の整数のために2つの別々の方法を作りました。

class String
  def numeric?
    !self.match(/[^0-9]/)
  end

  def positive_integer?
    self.to_i > 0
  end

  def nonnegative_integer?
    self.to_i > 0 or self == '0'
  end
end

ベンチマークコードは次のとおりです。

require 'benchmark'
include Benchmark

bmbm(100) do |x|
  x.report('numeric?') do
    "some invalid string".numeric?
  end

  x.report('positive_integer?') do
    "some invalid string".positive_integer?
  end

  x.report('nonnegative_integer?') do
    "some invalid string".nonnegative_integer?
  end
end

結果:

numeric?
0.000000   0.000000   0.000000 (  0.000045)
positive_integer?
0.000000   0.000000   0.000000 (  0.000012)
nonnegative_integer?
0.000000   0.000000   0.000000 (  0.000015)

このマイクロベンチマークでは、より高速であるように見えpositive_integer?ます。nonnegative_integer?

integer?最後に、補足として、同様の方法でメソッドを定義できます。

class String
  def integer?
    self.to_i.to_s == self
  end
end
于 2011-04-28T02:32:58.357 に答える
1

2番目の文字列は、数値以外の文字列の場合、最初の不良文字で拒否されるため、より早く終了します。

また、String#to_iメソッドを確認してください-おそらくあなたが望むことをします:
http ://www.ruby-doc.org/core/classes/String.html#M000787

于 2009-08-17T09:24:47.420 に答える
1

これが速いかどうかはわかりませんが、私は好きです:

class String
 def numeric?
    true if Integer(object) rescue false
 end
end

負の数も処理します。また、将来フロートをサポートしたい場合は、Float()を使用してください。

于 2009-08-17T09:35:10.723 に答える
0

単純なベンチマークによると、私は専門家のベンチマークではありませんが、2番目のアプローチの方が高速であるため、これは有効なベンチマークではない可能性があります:http: //pastie.org/586777

Zalusの論理は正しいです。無効な文字列を確認する必要があるのは1回だけです。

于 2009-08-18T05:53:58.063 に答える
0

知らせ

n = '1234'
n.to_i.to_s == n
=> true

n2 = '1.3'
n.to_i.to_s == n2
=> false

正と負の整数では機能しますが、8進数/ 16進数の表現、浮動小数点数などでは機能しません。最高の(テストされていない)パフォーマンスは得られない可能性がありますが、時期尚早の最適化で時間を無駄にすることはありません。

于 2012-07-31T00:34:45.503 に答える