仮定
- 曜日は
Mo
、Tu
、We
、Th
、Fr
、Sa
と表記されSu
ます。
- 時刻は有効です。正規表現の数字のシーケンスと一致するだけです。
解決
この正規表現を使用できます (スペースを柔軟に設定できます):
(Mo|Tu|We|Th|Fr|Sa|Su)(?=(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\d+:\d+) *+- *+(\d+:\d+))
上記の正規表現は非常に厳密です。カンマ区切りのリストに現在の曜日と時間範囲の間に何か他のものが含まれている場合 (例: Su, Somethingelse 02:12 - 3:45
)、一致は生成されません。
文字列の形式が正しいと完全に確信していて、データを抽出したいだけなら、この緩やかな正規表現で十分です:
([a-zA-Z]+)(?=\D+(\d+:\d+)\D+(\d+:\d+))
それらを文字列リテラルに入れる:
"(Mo|Tu|We|Th|Fr|Sa|Su)(?=(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\\d+:\\d+) *+- *+(\\d+:\\d+))"
"([a-zA-Z]+)(?=\\D+(\\d+:\\d+)\\D+(\\d+:\\d+))"
説明
(Mo|Tu|We|Th|Fr|Sa|Su)(?=(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\d+:\d+) *+- *+(\d+:\d+))
(Mo|Tu|We|Th|Fr|Sa|Su)
: 曜日の 1 つに一致します。
(?=(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\d+:\d+) *+- *+(\d+:\d+))
:ゼロ幅(テキストは消費されません) の正の先読み (内部のパターンが一致する場合は続行できます。そうでない場合は、一致に失敗してバックトラックします)。によって指定され(?=pattern)
ます。
中の柄は(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+(\d+:\d+) *+- *+(\d+:\d+)
. ここでは、現在の曜日の後のテキストの部分を照合し、時刻を取得しようとしています。
(?: *+, *+(?:Mo|Tu|We|Th|Fr|Sa|Su))* *+
: 曜日の後に、他の曜日をコンマで区切ることができます。
(\d+:\d+) *+- *+(\d+:\d+)
: 次に時間範囲です。
いくつかの *+
(スペース、アスタリスク、プラス) シーケンスを確認できます。 *
は、 0 個以上*
の空白文字に一致することを意味しますが、貪欲に、バックトラックは許可されます。は所有 *+
格です。つまり、バックトラッキングを許可しません。これは、不要な作業を行わないようにするための最適化と考えることができます。
([a-zA-Z]+)(?=\D+(\d+:\d+)\D+(\d+:\d+))
この例では、入力文字列内のアルファベット文字のシーケンスは曜日のみであると想定しています。また、数字が存在できるのはタイムスタンプだけだと思います。