文字列が数値 (浮動小数点) であるかどうかを確認するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/354038

質問

Python で文字列を数値として表現できるかどうかを確認する最善の方法は何ですか?

私が現在持っている機能は次のとおりです。

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

これは醜くて遅いだけでなく、不格好に見えます。ただし、呼び出しているため、より良い方法が見つかりませんでした float main 関数ではさらに悪いです。

役に立ちましたか?

解決

るだけでなく、醜いと

い紛争です。

A regexまたはその他の文字列の構文解析方法であるuglierと遅くなります。

なんなのかと何かできるのです。この機能に戻ります。Try/Catch紹介しないが多く架で最も一般的例外で獲れずに幅広い検索のスタックフレームに。

の問題に関連する数値変換関数は二種類の結果

  • 多くの場合、番号は有効
  • ステータスコード(例えば、errno)または例外が有効ときの解析が続けられます。

C(一例として)hacksこのころより有効なものになります。Pythonを配置で明確に説明します。

と思いコードを行うことの相性もバッチリです。●

他のヒント

浮動小数点数の代わりに (正の符号なし) 整数を解析したい場合は、 isdigit() 文字列オブジェクトの関数。

>>> a = "03523"
>>> a.isdigit()
True
>>> b = "963spam"
>>> b.isdigit()
False

文字列メソッド - isdigit(): Python2, Python3

Unicode 文字列に関するものもありますが、これについてはあまり詳しくありませんUnicode - 10 進数か 10 進数か

TL; DR の最適なソリューションであるs.replace('.','',1).isdigit()

私はいくつかの<のhref = "http://nbviewer.ipython.org/github/rasbt/One-Python-benchmark-per-day/blob/master/ipython_nbs/day6_string_is_number.ipynb?create=1" のrelをしました異なるアプローチを比較する = "noreferrer">ベンチマーク

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

import re    
def is_number_regex(s):
    """ Returns True is string is a number. """
    if re.match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()
文字列が数値でない場合は、

、を除くブロックはかなり遅いです。しかし、もっと重要なのは、試し-除く方法が正しく指数表記を扱う唯一の方法である。

funcs = [
          is_number_tryexcept, 
          is_number_regex,
          is_number_repl_isdigit
          ]

a_float = '.1234'

print('Float notation ".1234" is not supported by:')
for f in funcs:
    if not f(a_float):
        print('\t -', f.__name__)

フロート表記」0.1234" はによってサポートされていません。 - is_number_regex

scientific1 = '1.000000e+50'
scientific2 = '1e50'


print('Scientific notation "1.000000e+50" is not supported by:')
for f in funcs:
    if not f(scientific1):
        print('\t -', f.__name__)




print('Scientific notation "1e50" is not supported by:')
for f in funcs:
    if not f(scientific2):
        print('\t -', f.__name__)

科学的表記法 "1.000000e + 50" でサポートされていません - is_number_regex
- is_number_repl_isdigit

:科学的表記「1e50は」によってサポートされていません。 - is_number_regex
- is_number_repl_isdigit

編集:ベンチマーク結果

import timeit

test_cases = ['1.12345', '1.12.345', 'abc12345', '12345']
times_n = {f.__name__:[] for f in funcs}

for t in test_cases:
    for f in funcs:
        f = f.__name__
        times_n[f].append(min(timeit.Timer('%s(t)' %f, 
                      'from __main__ import %s, t' %f)
                              .repeat(repeat=3, number=1000000)))

以下の機能をテストしたところ、

from re import match as re_match
from re import compile as re_compile

def is_number_tryexcept(s):
    """ Returns True is string is a number. """
    try:
        float(s)
        return True
    except ValueError:
        return False

def is_number_regex(s):
    """ Returns True is string is a number. """
    if re_match("^\d+?\.\d+?$", s) is None:
        return s.isdigit()
    return True


comp = re_compile("^\d+?\.\d+?$")    

def compiled_regex(s):
    """ Returns True is string is a number. """
    if comp.match(s) is None:
        return s.isdigit()
    return True


def is_number_repl_isdigit(s):
    """ Returns True is string is a number. """
    return s.replace('.','',1).isdigit()

 loading=

"ここに画像の説明を入力します。
文字列「NaNの」

あなたが考慮に入れたいことは1つの例外があります

あなたはis_numberは、Pythonが(アイデンティティの問題について話)数ではない数のその表現に変換して動作しません「のNaN」このコードのFALSEを返したい場合:

は、
>>> float('NaN')
nan

そうでなければ、私は実際に私は今、広範囲に使用しているコードの部分のためにあなたに感謝する必要があります。 :)

G

これはどうます:

'3.14'.replace('.','',1).isdigit()

1、または全く存在しない場合にのみtrueを返します「」数字の文字列のます。

'3.14.5'.replace('.','',1).isdigit()

falseを返します。

編集:別のコメントを見ただけで... 他の例について.replace(badstuff,'',maxnum_badstuff)の追加は行うことができます。あなたは、任意の調味料、塩を渡すとされていない場合(参考: XKCD#974 の)これは問題ないでしょう:P

更新アルフェが指摘した後、あなたは複雑なハンドルとして別途フロートをチェックする必要はありません両方ます:

def is_number(s):
    try:
        complex(s) # for int, long, float and complex
    except ValueError:
        return False

    return True
<時間>

以前に言った:いくつかのまれなケースでは、あなたはまた、浮動小数点で表現できない複雑な数字(例えば1 + 2I)、をチェックする必要がある場合がありますされています:

def is_number(s):
    try:
        float(s) # for int, long and float
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False

    return True
  

醜いと遅いされており、だけでなく、不格好なようです。

これは、いくつかの慣れかかる場合がありますが、これはそれを行うためのニシキヘビの方法です。すでに指摘したように、選択肢が悪化しています。しかし、物事をこのように行うの一つの他の利点がある:。多型は、

ダックタイピングの背後にある中心的な考えは、「それは歩くとアヒルのように話している場合、それはアヒルだ。」ということですあなたは、あなたが何かがfloatに変換することが可能かどうかを判断する方法を変更することができるように文字列をサブクラス化する必要があると判断した場合は?それとも何を完全に他のオブジェクトをテストすることを決定した場合は?あなたは上記のコードを変更せずにこれらの事を行うことができます。

他の言語インターフェースを使用してこれらの問題を解決します。私は別のスレッドのために優れているソリューションの分析を保存します。ポイントは、しかし、Pythonは方程式のダックタイピング側に明らかであるということです、そしてあなたはおそらく、あなたが(Pythonで多くのプログラミングを行う上で計画している場合、このような構文に慣れる必要があるとしているが、それは意味するものではありませんあなたは)当然のことながら、それを好きに持っています。

あなたが考慮に入れる場合があります。

もうひとつ:Pythonは他の言語(30X例えばネットよりも高速)の多くに比べて例外をスローし、キャッチにはかなり速いです。ヘック、言語自体にも非例外、通常のプログラムの条件(あなたがforループを使用するたびに)通信するために、例外をスローします。あなたは重大な問題に気づくまで、このように、私はこのコードのパフォーマンスの側面についてはあまり心配しないでしょう。

intこれを使用してください

>>> "1221323".isdigit()
True

しかし、私たちが;-)いくつかのトリックを必要とするfloatため。すべての浮動小数点数は、一点を持っている...

>>> "12.34".isdigit()
False
>>> "12.34".replace('.','',1).isdigit()
True
>>> "12.3.4".replace('.','',1).isdigit()
False

また、負の数のためだけに、lstrip()追加

>>> '-12'.lstrip('-')
'12'

そして今、我々は普遍的な方法を取得します:

>>> '-12.34'.lstrip('-').replace('.','',1).isdigit()
True
>>> '.-234'.lstrip('-').replace('.','',1).isdigit()
False

だけを模倣C#

クライアントまで、フルのC#があり異なる二つの機能を取り扱う解析のスカラー値:

  • Float.Parse()
  • Float.TryParse()

float.parse():

def parse(string):
    try:
        return float(string)
    except Exception:
        throw TypeError

注意:だがなぜ変更しましたが、例外は例外, この文書.

float.try_parse():

def try_parse(string, fail=None):
    try:
        return float(string)
    except Exception:
        return fail;

注意:おすすめのbooleanは'False'にない価値タイプです。ながとことを示します。もちろん、いいに異なるものを変更できなパラメータは何をしています。

延長するfloatなどのparse()'と'try_parse()'る必要がありまmonkeypatchの'float'クラスを追加します。

したい場合に尊重し、既存の機能はコードのようなもの:

def monkey_patch():
    if(!hasattr(float, 'parse')):
        float.parse = parse
    if(!hasattr(float, 'try_parse')):
        float.try_parse = try_parse

SideNote:個人的に好きなモンキパンチングがうん濫用される言語のい場合はこのがYMMV.

使用量:

float.parse('giggity') // throws TypeException
float.parse('54.3') // returns the scalar value 54.3
float.tryParse('twank') // returns None
float.tryParse('32.2') // returns the scalar value 32.2

大Sage Pythonasと言われる聖Sharpisus,"何もできない事がある;いきなりありがとうございます。"

文字列の数 try: except: 実際に以下の正規表現オブジェクト文字列の有効な番号、regexが遅くなります。なので、適切な方法によって異なり入力します。

だくださいますようお願いい性能がbindをお使いいただけますので第三者のモジュールと呼ばれ fastnumbers を提供する機能と呼ばれるもの isfloat.開いた。ってその成果をタイミングです。


from __future__ import print_function
import timeit

prep_base = '''\
x = 'invalid'
y = '5402'
z = '4.754e3'
'''

prep_try_method = '''\
def is_number_try(val):
    try:
        float(val)
        return True
    except ValueError:
        return False

'''

prep_re_method = '''\
import re
float_match = re.compile(r'[-+]?\d*\.?\d+(?:[eE][-+]?\d+)?$').match
def is_number_re(val):
    return bool(float_match(val))

'''

fn_method = '''\
from fastnumbers import isfloat

'''

print('Try with non-number strings', timeit.timeit('is_number_try(x)',
    prep_base + prep_try_method), 'seconds')
print('Try with integer strings', timeit.timeit('is_number_try(y)',
    prep_base + prep_try_method), 'seconds')
print('Try with float strings', timeit.timeit('is_number_try(z)',
    prep_base + prep_try_method), 'seconds')
print()
print('Regex with non-number strings', timeit.timeit('is_number_re(x)',
    prep_base + prep_re_method), 'seconds')
print('Regex with integer strings', timeit.timeit('is_number_re(y)',
    prep_base + prep_re_method), 'seconds')
print('Regex with float strings', timeit.timeit('is_number_re(z)',
    prep_base + prep_re_method), 'seconds')
print()
print('fastnumbers with non-number strings', timeit.timeit('isfloat(x)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with integer strings', timeit.timeit('isfloat(y)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print('fastnumbers with float strings', timeit.timeit('isfloat(z)',
    prep_base + 'from fastnumbers import isfloat'), 'seconds')
print()

Try with non-number strings 2.39108395576 seconds
Try with integer strings 0.375686168671 seconds
Try with float strings 0.369210958481 seconds

Regex with non-number strings 0.748660802841 seconds
Regex with integer strings 1.02021503448 seconds
Regex with float strings 1.08564686775 seconds

fastnumbers with non-number strings 0.174362897873 seconds
fastnumbers with integer strings 0.179651021957 seconds
fastnumbers with float strings 0.20222902298 seconds

ご覧のとおり

  • try: except: した高速数値入力が非常に遅いため無効な入力
  • regexが非常に効率的な入力が無効にな
  • fastnumbers 勝場合

私は、これは特に古いです知っているが、私はこれを見つける方いずれにも非常に貴重である可能性が最も高い投票の回答から欠落情報を網羅信じる答えを追加することになります:

あなたが受け入れられるための任意の入力が必要な場合は、

次の方法のそれぞれについては、カウントとそれらを接続します。 (私たちはなど、ボーカルの整数の定義ではなく、0-255を使用していると仮定。)

x.isdigit() xが整数であるかどうかをチェックするためにうまく機能します。

x.replace('-','').isdigit() xが負であるかどうかをチェックするに適しています(チェック - 最初の位置で)ます。

x.replace('.','').isdigit() xが小数かどうかをチェックするためにうまく機能します。

x.replace(':','').isdigit() xが比率であるかどうかをチェックするためにうまく機能します。

x.replace('/','',1).isdigit() xは分数であるかどうかをチェックするためにうまく機能します。

鋳造は浮くし、フロート()は、特にそれだけのために意味されているので引くとValueErrorは、おそらく最速の方法です。文字列の解析(正規表現など)を必要と何か他のものは、おそらくそれは、この操作のためにチューニングされていないという事実に遅くなる原因となります。私の$ 0.02

あなたはUnicode文字列を使用することができ、彼らはあなたが欲しいものだけで行うための方法があります:

>>> s = u"345"
>>> s.isnumeric()
True

それともます:

>>> s = "345"
>>> u = unicode(s)
>>> u.isnumeric()
True

http://www.tutorialspoint.com/python/string_isnumeric.htm

http://docs.python.org/2/howto/unicode.htmlする

この答えを提供ッガイドを有する機能例の文字列は:

  • 正の整数
  • 正/負の整数/float
  • 廃棄については受け取っ"NaN"は番号の文字列をチェック。

チェック文字列の場合は 整数

使 str.isdigit() チェックかどうか指定された文字列が 整数となります。

サンプルの実験結果:

# For digit
>>> '1'.isdigit()
True
>>> '1'.isalpha()
False

チェックのための文字列として正/負の整数/float

str.isdigit() を返します False の場合は文字列である 番号またはフロート番号です。例えば:

# returns `False` for float
>>> '123.3'.isdigit()
False
# returns `False` for negative number
>>> '-123'.isdigit()
False

したい場合 確認のための 整数 float, しくカスタム関数のチェックして:

def is_number(n):
    try:
        float(n)   # Type-casting the string to `float`.
                   # If string is not a valid `float`, 
                   # it'll raise `ValueError` exception
    except ValueError:
        return False
    return True

サンプル実行します:

>>> is_number('123')    # positive integer number
True

>>> is_number('123.4')  # positive float number
True

>>> is_number('-123')   # negative integer number
True

>>> is_number('-123.4') # negative `float` number
True

>>> is_number('abc')    # `False` for "some random" string
False

捨て"NaN"は番号の文字列を確認しながら、数

上記の機能に戻りま True の"NAN"は番号の文字列がPythonで有効なfloat値を表すのではない。例えば:

>>> is_number('NaN')
True

るかを確認するため、その数は"NaN"をご利用いただくことが math.isnan()

>>> import math
>>> nan_num = float('nan')

>>> math.isnan(nan_num)
True

は行わない場合は輸入の追加図書館で確認する場合があり単にチェックでと比較することそのものを使用 ==.Pythonを返します Falsenan floatとを比較します。例えば:

# `nan_num` variable is taken from above example
>>> nan_num == nan_num
False

そのため、上記 機能 is_number 更新可能な復帰 False のための "NaN"

def is_number(n):
    is_number = True
    try:
        num = float(n)
        # check for "nan" floats
        is_number = num == num   # or use `math.isnan(num)`
    except ValueError:
        is_number = False
    return is_number

サンプル実行します:

>>> is_number('Nan')   # not a number "Nan" string
False

>>> is_number('nan')   # not a number string "nan" with all lower cased
False

>>> is_number('123')   # positive integer
True

>>> is_number('-123')  # negative integer
True

>>> is_number('-1.12') # negative `float`
True

>>> is_number('abc')   # "some random" string
False

PS:各操作のための各チェックの種類によって番号付属の追加オーバーヘッド。バージョンを選択の is_number 機能を組み合わせます。

私は最速である方法見てみたかったです。全体的に最良かつ最も一貫性のある結果がcheck_replace関数によって与えられました。最速の結果はcheck_exception関数で与えられるが、例外発射がなかった場合にのみ、た - そのコードの意味は、最も効率的であるが、例外をスローのオーバーヘッドが非常に大きいです。

成功したキャストをチェックすることは正確である唯一の方法であることに注意してください、例えば、これはと<=>動作しますが、他の2つのテスト機能が有効なフロートのためにFalseを返します。

huge_number = float('1e+100')

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

import time, re, random, string

ITERATIONS = 10000000

class Timer:    
    def __enter__(self):
        self.start = time.clock()
        return self
    def __exit__(self, *args):
        self.end = time.clock()
        self.interval = self.end - self.start

def check_regexp(x):
    return re.compile("^\d*\.?\d*$").match(x) is not None

def check_replace(x):
    return x.replace('.','',1).isdigit()

def check_exception(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

to_check = [check_regexp, check_replace, check_exception]

print('preparing data...')
good_numbers = [
    str(random.random() / random.random()) 
    for x in range(ITERATIONS)]

bad_numbers = ['.' + x for x in good_numbers]

strings = [
    ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randint(1,10)))
    for x in range(ITERATIONS)]

print('running test...')
for func in to_check:
    with Timer() as t:
        for x in good_numbers:
            res = func(x)
    print('%s with good floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in bad_numbers:
            res = func(x)
    print('%s with bad floats: %s' % (func.__name__, t.interval))
    with Timer() as t:
        for x in strings:
            res = func(x)
    print('%s with strings: %s' % (func.__name__, t.interval))

ここでは、2017年のMacBook Proの13上のPython 2.7.10での結果は次のとおりです:

check_regexp with good floats: 12.688639
check_regexp with bad floats: 11.624862
check_regexp with strings: 11.349414
check_replace with good floats: 4.419841
check_replace with bad floats: 4.294909
check_replace with strings: 4.086358
check_exception with good floats: 3.276668
check_exception with bad floats: 13.843092
check_exception with strings: 15.786169

ここでは、2017年のMacBook Proの13上のPython 3.6.5での結果は次のとおりです:

check_regexp with good floats: 13.472906000000009
check_regexp with bad floats: 12.977665000000016
check_regexp with strings: 12.417542999999995
check_replace with good floats: 6.011045999999993
check_replace with bad floats: 4.849356
check_replace with strings: 4.282754000000011
check_exception with good floats: 6.039081999999979
check_exception with bad floats: 9.322753000000006
check_exception with strings: 9.952595000000002

ここでは、2017年のMacBook Proの13のPyPy 2.7.13での結果は次のとおりです:

check_regexp with good floats: 2.693217
check_regexp with bad floats: 2.744819
check_regexp with strings: 2.532414
check_replace with good floats: 0.604367
check_replace with bad floats: 0.538169
check_replace with strings: 0.598664
check_exception with good floats: 1.944103
check_exception with bad floats: 2.449182
check_exception with strings: 2.200056

だから、ナン、無限大と複素数をチェックし、それをすべて一緒に置くために(それは彼らがjに指定されていると思われる、ないI、すなわち1 + 2J)、それは、その結果ます:

def is_number(s):
    try:
        n=str(float(s))
        if n == "nan" or n=="inf" or n=="-inf" : return False
    except ValueError:
        try:
            complex(s) # for complex
        except ValueError:
            return False
    return True

った速試験とします。きった場合には、文字列 する複数の されていない除く 戦略は、最高速が可能です。場合、文字列 ないと考 する数 ご興味のある 整数 チェックでworthsい試験(isdigitスなのか'-').ご興味のある方はチェックfloat数使用の されていない除く コードwhitoutます。

私は、文字列が基本タイプ(フロート、int型、STR、ブール値)にキャストするかどうかを決定する必要がありました。インターネット上で何かを見つけていない後、私はこれを作成します:

def str_to_type (s):
    """ Get possible cast type for a string

    Parameters
    ----------
    s : string

    Returns
    -------
    float,int,str,bool : type
        Depending on what it can be cast to

    """    
    try:                
        f = float(s)        
        if "." not in s:
            return int
        return float
    except ValueError:
        value = s.upper()
        if value == "TRUE" or value == "FALSE":
            return bool
        return type(s)

str_to_type("true") # bool
str_to_type("6.0") # float
str_to_type("6") # int
str_to_type("6abc") # str
str_to_type(u"6abc") # unicode       

あなたはタイプをキャプチャし、それを使用することができます。

s = "6.0"
type_ = str_to_type(s) # float
f = type_(s) 

入力の場としており

a="50" b=50 c=50.1 d="50.1"


1一般入力:

を入力することが可能です。

見つけるかどうか指定された変数.数値の文字列のオプションに署名、桁数、オプション小数部分とオプションの指数です。このように+0123.45e6は有効数字の値です。進数(例えば0xf4c3b00c)およびバイナリーなど0b10100111001)表記はできません。

is_numeric 機能

import ast
import numbers              
def is_numeric(obj):
    if isinstance(obj, numbers.Number):
        return True
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            #if used + or - in digit :
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

試験:

>>> is_numeric("54")
True
>>> is_numeric("54.545")
True
>>> is_numeric("0x45")
True

is_float 機能

見つけるかどうか指定された変数は浮いてしまうからなのです。floatの文字列のオプションに署名、番号の桁...

import ast

def is_float(obj):
    if isinstance(obj, float):
        return True
    if isinstance(obj, int):
        return False
    elif isinstance(obj, str):
        nodes = list(ast.walk(ast.parse(obj)))[1:]
        if not isinstance(nodes[0], ast.Expr):
            return False
        if not isinstance(nodes[-1], ast.Num):
            return False
        if not isinstance(nodes[-1].n, float):
            return False
        nodes = nodes[1:-1]
        for i in range(len(nodes)):
            if i % 2 == 0:
                if not isinstance(nodes[i], ast.UnaryOp):
                    return False
            else:
                if not isinstance(nodes[i], (ast.USub, ast.UAdd)):
                    return False
        return True
    else:
        return False

試験:

>>> is_float("5.4")
True
>>> is_float("5")
False
>>> is_float(5)
False
>>> is_float("5")
False
>>> is_float("+5.4")
True

ast?


の2の場合はこの変数の内容 文字列:

使用 str.isdigit() 方法

>>> a=454
>>> a.isdigit()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'isdigit'
>>> a="454"
>>> a.isdigit()
True

3-数値入力:

検出int値:

>>> isinstance("54", int)
False
>>> isinstance(54, int)
True
>>> 

検出float:

>>> isinstance("45.1", float)
False
>>> isinstance(45.1, float)
True

RyanNが示唆

  

あなたがNaNとInfを、X =フロート(S)への変更ラインのためにFalseを返すようにしたい場合は、リターン(X == x)と(X! - 1 = X)。これはInfのとNaNを除くすべての山車のためにtrueを返します。

しかし、十分に大きな山車のために、x-1 == x trueを返すので、これは、かなりの作業を行いません。例えば、2.0**54 - 1 == 2.0**54

私はあなたのソリューションは大丈夫だと思います。

私は正規表現が合理的にクリーンで正確かつ高速にすることができ、不当だと思うこれらの答えに向けた正規表現憎しみがたくさんだ、と述べました。それは本当にあなたが何をしようとしてに依存します。元の質問は、どのようにあなたが(あなたのタイトルごとに)「という文字列が数値(float型)として表すことができるかどうかを確認」することができました。おそらくあなたは、その場合、あなたの試みで/多くの意味を作る以外、それが有効だと確認したら、数値/ float型の値を使用したいと思います。しかし、いくつかの理由で、あなただけのの文字列のはの数の後、正規表現でも正常に動作しますが、それが正しい取得するのは難しいこと。検証する場合など私は限りPythonが懸念しているフロートしている正規表現の答えのほとんどは、これまで、例えば、適切に(例えば、」0.7" のような)整数部なしで文字列を解析していないと思います。そして、それは小数部分が必要とされていない単一の正規表現でチェックするために少しトリッキーです。私はこれを表示するために、2つの正規表現を含めました。

これは、「数」が何であるかのように興味深い問題を提起しません。あなたはPythonでfloatとして有効であり、「INF」が含まれていますか?それとも、「数字」です番号が含まれますが、おそらく(例えばフロートmaxよりも大きい数字として)Pythonで表現することはできません。

曖昧さは、あなたが数字を解析する方法でもあります。例えば、どのような「-20」についてはどうですか?これは「数」となっていますか?これは「20」を表現するための法的な方法ですか? Pythonは(実際にそれが表現として扱われますので、これはですが)が、フロート「-20 = VARを」あなたがやらせと20に設定します。(「 - 20」)は動作しません。

Pythonはそれらを解析すると、

とにかく、より多くの情報なしに、ここで私は信じている正規表現はすべてint型をカバーだと山車の<全角> の

# Doesn't properly handle floats missing the integer part, such as ".7"
SIMPLE_FLOAT_REGEXP = re.compile(r'^[-+]?[0-9]+\.?[0-9]+([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           mantissa (34)
                            #                    exponent (E+56)

# Should handle all floats
FLOAT_REGEXP = re.compile(r'^[-+]?([0-9]+|[0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?$')
# Example "-12.34E+56"      # sign (-)
                            #     integer (12)
                            #           OR
                            #             int/mantissa (12.34)
                            #                            exponent (E+56)

def is_float(str):
  return True if FLOAT_REGEXP.match(str) else False

いくつかの例のテスト値:

True  <- +42
True  <- +42.42
False <- +42.42.22
True  <- +42.42e22
True  <- +42.42E-22
False <- +42.42e-22.8
True  <- .42
False <- 42nope

私はまた、あなたが言及した機能を使用したが、すぐに私は、「ナン」、「Infの」などという文字列に気づき、それが数として考えられている変化をです。だから私はあなたが入力のこれらのタイプにはfalseを返しますと「1E3」の変種を失敗することはありませんあなたの関数のバージョンを、改善提案ます:

def is_float(text):
    try:
        float(text)
        # check for nan/infinity etc.
        if text.isalpha():
            return False
        return True
    except ValueError:
        return False
import re
def is_number(num):
    pattern = re.compile(r'^[-+]?[-0-9]\d*\.\d*|[-+]?\.?[0-9]\d*$')
    result = pattern.match(num)
    if result:
        return True
    else:
        return False


​>>>: is_number('1')
True

>>>: is_number('111')
True

>>>: is_number('11.1')
True

>>>: is_number('-11.1')
True

>>>: is_number('inf')
False

>>>: is_number('-inf')
False

このコードは、正規表現を使用せずに、指数、浮動小数点数、および整数を処理します。

return True if str1.lstrip('-').replace('.','',1).isdigit() or float(str1) else False

ここでそれをやって、私の簡単な方法です。のは、私はいくつかの文字列をループしていると私は、彼らが数字であることが判明する場合は、配列にそれらを追加したいとしましょう。

try:
    myvar.append( float(string_to_check) )
except:
    continue

それは数であることが判明した場合、あなたが文字列でやりたいものは何でも動作とmyvar.apppendを交換してください。アイデアは、フロート()操作を使用して、文字列が数値であるかどうかを判断するために返されたエラーを使用しようとすることです。

あなたはTrueとFalseよりも有用な値を返すことで便利な方法で例外手法を一般化することができます。たとえば、この関数は、文字列の周りに引用符を置きますが、数字だけを残します。これは、私はR.のためのいくつかの変数定義を作成するために迅速かつ汚れたフィルターのために必要なものだけです。

import sys

def fix_quotes(s):
    try:
        float(s)
        return s
    except ValueError:
        return '"{0}"'.format(s)

for line in sys.stdin:
    input = line.split()
    print input[0], '<- c(', ','.join(fix_quotes(c) for c in input[1:]), ')'

私はこのスレッドに私を導いた問題に取り組んでいた、すなわち、どのように最も直感的な方法で、文字列や数値へのデータの収集を変換します。私は私が必要とする二つの方法で異なっていたことを、元のコードを読んだ後に実現ます:

1 - 文字列が整数を表す場合、私は整数の結果を望んでいた。

2 - 私はデータ構造に固執する数値や文字列の結果を望んでいた。

私はこの誘導体を生成するために元のコードを適応:

def string_or_number(s):
    try:
        z = int(s)
        return z
    except ValueError:
        try:
            z = float(s)
            return z
        except ValueError:
            return s

これを試してみてください。

 def is_number(var):
    try:
       if var == int(var):
            return True
    except Exception:
        return False

ユーザーのヘルパー関数ます:

def if_ok(fn, string):
  try:
    return fn(string)
  except Exception as e:
    return None

そして

if_ok(int, my_str) or if_ok(float, my_str) or if_ok(complex, my_str)
is_number = lambda s: any([if_ok(fn, s) for fn in (int, float, complex)])

-

それはすべてのケースを処理し、次の使用

import re
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3') 
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '.3')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3sd')
a=re.match('((\d+[\.]\d*$)|(\.)\d+$)' ,  '2.3')
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top