0

次の正規表現ルールを理解しようとしています。

import re

time_format = r"(?:(?P<weeks>\d+)\W*(?:weeks?|w),?)?\W*(?:(?P<days>\d+)\W*(?:days?|d),?)?\W*(?:(?P<hours>\d+):(?P<minutes>\d+)(?::(?P<seconds>\d+)(?:\.(?P<microseconds>\d+))?)?)?"
time_matcher = re.compile(time_format)
time_matches = time_matcher.match(td_str)

このルールを設定td_str = '0:10'すると、次の結果が得られます。

{'days': None,
 'hours': '0',
 'microseconds': None,
 'minutes': '01',
 'seconds': None,
 'weeks': None}

設定td_str = '0:0:10'すると、次の結果が得られます。

{'days': None,
 'hours': '0',
 'microseconds': None,
 'minutes': '0',
 'seconds': '01',
 'weeks': None}

0:10正規表現ルールを変更して、0分+ 10秒として解釈されるようにするにはどうすればよいですか?さらに、「1:20:1」は、1時間+20分+1秒として解釈する必要があります。

したがって、(正規表現を理解している限り)作成したい正規表現ルールは次のとおりです。[H:[M:]]S

EDIT1:私は正しいルールを作成したと思います[M:]S

time_format = r"((?P<minutes>\d+)?:?)(?P<seconds>\d+)"

これが正しい方法であることを誰かが確認できますか?

EDIT2: Edit1に示されているルールを拡張すると、次のように機能します(場合によっては)。

time_format = r"((((?P<hours>\d+)?:?)(?P<minutes>\d+))?:?)(?P<seconds>\d+)"

ただし、私が言うとtime='1:10'、これは1分10秒ではなく、1時間1分0秒に誤って変換されます。

EDIT3:これは、正規表現を使用せずに、今のところ問題を解決した方法です。正規表現を使用して同じことを実現する方法を知りたいです。

# defaults
days = 0
hours = 0
minutes = 0
seconds = 0
microseconds = 0

split_fields = time_string.split(':')
nbr_fields = len(split_fields)

if nbr_fields == 0: # should never happen
    pass
if nbr_fields == 1:
    seconds = int(split_fields[0])
elif nbr_fields == 2:
    minutes = int(split_fields[0])
    seconds = int(split_fields[1])
elif nbr_fields == 3:
    hours = int(split_fields[0])
    minutes = int(split_fields[1])
    seconds = int(split_fields[2])
else: # in case there's more than 3 fields ...
    hours = int(split_fields[-3])
    minutes = int(split_fields[-2])
    seconds = int(split_fields[-1])
4

1 に答える 1

0

正規表現の一致する秒の部分はオプションであるため、次の文字で指定したとおりに一致させることができます?。同じことがマイクロ秒フィールドにも当てはまります。

正規表現の一部だけを取得すると、H:M[:S.[USEC]]次のようになります。

(?P<hours>\d+):(?P<minutes>\d+)(?::(?P<seconds>\d+)(\.(?P<microseconds>\d+))?)?

この種のマッチングを行うために、常に正規表現を使用する必要があるわけではありません。要素を分割する独自のパーサーを作成する方が簡単な場合があります。たとえば、 を使用しstring.split(':')ます。後でコードを読み返すと、より理解しやすいかもしれません。

(秒とマイクロ秒の間にコロンがあることに気付きました。上記の正規表現は、それを考慮して変更する必要があります。リストされた正規表現は、01:02:03.456 に一致します。

編集:

のように正規表現を構成することは可能(S)|(M:S)|(H:M:S)ですが、グループ名は複数回表示できないため、名前付きグループでは機能しません。問題は、エンジンが先を見て、一番右のトークンを最初に照合してから、左のトークンを照合することです。文字列は左から右にスキャンされて一致するものを探します。その結果、少なくとも名前付きグループを使用している場合は、フィールドを明確に記述する方法がありません。

名前付きグループを含まない別の解決策は、次のようなより一般的な式を使用し、(\d+)(:\d+)?(:\d+)?None ではない返されたグループを見て、その意味を判断することです。グループが 1 の場合は S のみ、2 の場合は M:S など。

于 2012-08-28T11:14:09.150 に答える