0

文字列からいくつかのフィールドを抽出したいのですが、いくつあるかわかりません。正規表現を使用しましたが、理解できない問題がいくつかあります。

例えば:

  199  -> (199)
  199,200  -> (199,200)
  300,20,500 -> (300,20, 500)

試してみましたが、なかなかうまくいきません。誰かが私にいくつかのアドバイスを与えることができることを願っています。私は感謝します。

私が試した正規表現:

>>> re.match('^(\d+,)*(\d+)$', '20,59,199,300').groups()
('199,', '300')
// in this, I do not really care about ',' since I could use .strip(',') to trim that. 

私はいくつかのグーグルをしました:そしてre.findallを使おうとしました、しかし私はこれをどうやって得るのかわかりません:

>>> re.findall('^(\d+,)*(\d+)$', '20,59,199,300')
[('199,', '300')]

-------------------------------------------------- - - アップデート

全体の話をしなくても、この質問は混乱を招く可能性があることに気づきました。基本的に、crontab(または同様のもの)で定義された構文を検証したい

_VALID_EXPRESSIONの配列を作成します。これはネストされたタプルです。

 (field_1,
  field_2,
 )

field_1ごとに、2つのタプルがあります。

 field_1:   ((0,59),        (r'....', r'....'))
            valid_value   valid_format 

私のコードでは、次のようになります。

_VALID_EXPRESSION =  \
 12     (((0, 59), (r'^\*$', r'^\*/(\d+)$', r'^(\d+)-(\d+)$',
 13                 r'^(\d+)-(\d+)/(\d+)$', r'^(\d+,)*(\d+)$')),   # second
 14      ((0, 59), (r'^\*$', r'^\*\/(\d+)$', r'^(\d+)-(\d+)$',
 15                 r'^(\d+)-(\d+)/(\d+)$', r'^(\d+,)*(\d+)$')),   # minute
 16        .... )

私の解析関数では、すべてのグループを抽出して、それらが有効な値の範囲内にあるかどうかを確認するだけです。

私が必要とする正規表現の1つは、この文字列 '50,200,300'に正しく一致し、この場合はすべての数値を抽出できることです。(もちろんsplit()を使用することもできますが、本来の意図を裏切ることになります。そのため、そのアイデアは嫌いです。)

これがお役に立てば幸いです。

4

2 に答える 2

3

string.splitを使用しないのはなぜですか?

numbers = targetstr.split(',')
于 2013-02-28T18:36:20.397 に答える
1

正規表現を使用した最も簡単な解決策は次のとおりです。

r"(\d+,?)"

、、をfindall取得するために使用できます。または、コンマが必要ない場合:300,20,500

r"(\d+),?"

これは、1桁以上のグループに一致し、その後に0または1のコンマが続きます(グループには含まれません)。

どちらにしても:

>>> s = '300,20,500'
>>> r = re.compile(r"(\d+),?")
>>> r.findall(s)
['300', '20', '500']

ただし、Sahil Groverが指摘しているように、これらが入力文字列である場合、これは単に。を呼び出すことと同じs.split(',')です。入力文字列に数字以外の文字列が含まれている可能性がある場合、これにより数字文字列のみが一致するようになりますが、それでもおそらく。のように単純になりfilter(str.isdigit, s.split(','))ます。

sの代わりにstupleが必要な場合:intliststr

>>> tuple(map(int, r.findall(s)))
(300, 20, 500)

内包表記/ジェネレータ式がmap/filter呼び出しよりも読みやすい場合:

>>> tuple(int(x) for x in r.findall(s))
(300, 20, 500)

または、もっと簡単に:

>>> tuple(int(x) for x in s.split(',') if x.isdigit())
(300, 20, 500)

文字列が必要な場合は、もちろん、(300, 20, 500)を呼び出すだけでそれを行うことができますが、それを取得するためのはるかに簡単な方法があります。reprtuple

>>> '(' + s + ')'
'(300, 20, 500)'

元の正規表現:

'^(\d+,)*(\d+)$'

パターンには正確に2つのグループがあるため、…は正確に2つのグループを返します。^また、明示的にとをラップして$いるため、文字列全体と一致する必要があるため、findallここでは役に立ちません。(2つのグループの)まったく同じ1つの一致が検索されmatchます。

于 2013-02-28T18:35:35.410 に答える