0

Pythonスニペットの正規表現を作成したいと思います。

import re
pattern = "\d*\.?\d+[Ee]?[+-]?\d*"
r = re.compile(pattern)
txt = """
12
.12
12.5
12.5E4
12.5e4
12.4E+4
12E4
12e-4
"""
x = r.findall(txt)
print(x)

txtからのすべての有効な入力をフィルタリングするために、このコードは問題ありませんが、次のような無効な入力です。

.12e、12.3 + 4

どうすればこれを修正できますか?

4

8 に答える 8

1

従来の正規表現は次のようなものです。

pattern = (
    "(?:"
    r"\d+(?:\.\d+)(:?[Ee][-+]?\d+)"
    "|"
    r"\.\d+(:?[Ee][+-]?\d+)"
    ")"
)

しかし、あなたはいつでも簡単な方法で物事を行うことができます:

def is_number(x):
    try:
        float(x)
        return True
    except ValueError:
        return False
于 2012-10-23T20:17:21.730 に答える
1

正規表現パターンを使用することをお勧めします

^(?=\.?\d)\d*(?:\.\d*)?(?:[eE][+-]?\d+)?$
于 2012-10-23T20:24:08.533 に答える
1

必要のないときは正規表現を使用しないでください。どちらが有効かをPythonに判断させる方が、Pythonic [tm]の方が(そして簡単で信頼性が高く)なります。

results = []
for line in txt.split():
    try:
        float(line)
    except ValueError:
        pass
    else:
        results.append(line)
print results
于 2012-10-23T20:26:07.920 に答える
0

試すことができます:\d*\.?\d+(?:[Ee][+-]?\d+)?$。これにより、指数部分がグループとしてマークされます。$また、文字列の末尾と一致することを確認するためにを追加しました。

また、正規表現にはが含まれて\いるため、生の文字列リテラルを使用する必要があります。例:r'\n'、これはリテラル\nであり、改行文字ではありません。

より簡単な方法は、例外を使用float()してチェックすることValueErrorです。

于 2012-10-23T20:14:39.827 に答える
0

正規表現を次のように変更してみてください。

\d*\.?\d+(?:[Ee][+-]?\d+)?

これにより、eまたはEが存在する場合、常に少なくとも1桁の数字が存在するようになり、+およびは、または-の後に続く場合にのみ有効になります。eE

バックスラッシュが適切にエスケープされていることを確認するために、生の文字列リテラルを使用する必要があることに注意してください(特にこの文字列には影響しませんが\b、正規表現のようなものを使用しようとすると違いがわかります)。

pattern = r"\d*\.?\d+(?:[Ee][+-]?\d+)?"
于 2012-10-23T20:14:52.543 に答える
0

このような何かがそれを行う必要があります(テストされていません):

"\d*\.?\d+(?:[Ee][+-]\d)?\d*"
于 2012-10-23T20:19:04.837 に答える
0

これが、おそらくこれまでで最も単純な方法です。

^(\d*\.?\d+([Ee][+-]?\d+)?)$

^と$を、空白など、デリムにしたいものに置き換えます。

解決策の説明:

あなたの解決策

\d*\.?\d+[Ee]?[+-]?\d*

Eを数字なしで配置できるようにしました->したがって、私の最後に\d+を付けます。また、Eとオプションの+/-を作成し、その後にその必須の数字を1つのグループにまとめて(つまり、すべてを括弧で囲んで)、相互に存在しないようにしました。そのグループ全体([Ee] [+-]?\ d +)は、その概念なしであなたの数の例に対応するためにオプション(?)です。

于 2012-10-23T20:29:46.980 に答える
0

または、正規表現をまとめて回避するには、Pythonトークナイザーを使用して正規表現を見つけます。

test2.txt

いくつかのでこぼこ
2.341.7e2
もう少し
でこぼこ

サンプルコード

from tokenize import generate_tokens, NUMBER

source = open('test2.txt').readline
numbers = [ (val, eval(val)) for typ, val, _, _, _ in generate_tokens(source) if typ==NUMBER]
print numbers
# [('2.34', 2.34), ('1.7e2', 170.0)]
于 2012-10-23T20:31:59.477 に答える