2016-09-29 12 views
0

私は解析しようとしているものは以下のとおりです。私は正午のためのケータリングせずに、次の必要があり正規表現 - 午後5時、5.30午後、正午

8am, 12.10pm, 5.45pm 
8am, 11.30am 
12noon 
12 noon 
8 am 
7 pm. 

- それはキャプチャされません。上記のすべてのケース。

^([0-9]|0[0-9]|1[0-9]|2[0-3]).[0-5][0-9][a|p]m$ 
+0

この正規表現は '[\ d] {1,2}(\。[\ d] {1,2})の上のすべてのケースを解析すると思いますか?\ s ?(am | pm | noon) ' –

+0

最後の段落を削除して、トピックをオフトピックにして、正規表現のヘルプを求めてください。 –

+0

@CaioOliveira:あなたの努力は、午前9時9分、午後39時9分、正午99,99時間に一致しますが、いずれも有効な時間はありません。 –

答えて

1

検証は、正規表現の外で行われるべきであるエッジの例に基づいていますが、時間の。 私たちは正規表現内でそれを行うことができますが、パターンが本当に乱雑になります。

パターンの基本的な形は、このようにする必要があり、シンプルでストレートフォワード:

    \d{1,2}(\.\d{1,2})? ?([a|p]m|noon) 
    

    しかし、我々は時間の異なる部分を分離するために、いくつかの名前のグループを追加する必要があります

  1. 営業時間:(?<hours>\d{1,2})
  2. 分:(?<minutes>\d{1,2})
  3. 期間:(?<period>[ap]m|noon)

すべてのテーマと連動組み合わせる:@"(?<hours>\d{1,2})(\.(?<minutes>\d{1,2}))? ?(?<period>[ap]m|noon)"


次のコードは、ちょうどあなたの例で発見されたもの、およびそれを解析に人間が読める時間のように見える文字列のすべての部分をキャプチャTimeSpanオブジェクト:

var times = Regex.Matches(input, @"(?<hours>\d{1,2})(\.(?<minutes>\d{1,2}))? ?(?<period>[ap]m|noon)") 
    .Cast<Match>() 
    // parse parts of time 
    .Select(m => new 
    { 
     Hours = int.Parse(m.Groups["hours"].Value), 
     Minutes = m.Groups["minutes"].Success ? int.Parse(m.Groups["minutes"].Value) : 0, 
     IsAfternoon = Regex.IsMatch(m.Groups["period"].Value, "pm|noon"), 
    }) 
    // filter out invalid time 
    .Where(x => x.Hours <= 12 && x.Minutes <= 59) 
    // convert 
    .Select(x => new TimeSpan((x.Hours + (x.IsAfternoon ? 12 : 0)) % 24, x.Minutes, 0)); 

EDIT:私たちは奇妙なを持っています1pm = 13:00、2pm = 14:00、... 11pm = 23:00、12pm!= 24:00(しかし、12:00)。そして、上記の例ではこれを考慮していません。だからここ

修正:

var input = @" Monday 8am, 12.10pm, 5.45pm, 14:24||8:0|0:10|17:45"; 
var results = Regex.Matches(input, @"(?<hours>\d{1,2})([\.:](?<minutes>\d{2}))?(?<period>[ap]m|noon)?") 
    .Cast<Match>() 
    .Where(m => m.Groups["minutes"].Success || m.Groups["period"].Success) 
    .Select(m => new 
    { 
     Hours = int.Parse(m.Groups["hours"].Value), 
     Minutes = m.Groups["minutes"].Success ? int.Parse(m.Groups["minutes"].Value) : 0, 
     IsAfternoon = m.Groups["period"].Success ? Regex.IsMatch(m.Groups["period"].Value, "pm|noon") : (bool?)null 
    }) 
    .Dump() 
    .Where(x => (x.IsAfternoon != null ? x.Hours <= 12 : x.Hours < 24) && x.Minutes <= 59) 
    .Select(x => new TimeSpan(
     x.Hours == 12 && x.IsAfternoon == true 
      ? 12 
      : x.Hours + (x.IsAfternoon == true ? 12 : 0), 
     x.Minutes, 
     0)); 

結果:

午前8時00分00秒
12時10分00秒
午後五時45分00秒
午後02時24分○○秒
00:10:00
17:45:00

+0

これは実際に私が後にしたものです - RegexをC#解析と統合する方法はわかりませんでした。それはまだ正確に以下を解析しません - 特に12.10pmは00:10として解析します。それ以外にもうまくいきます。 月曜日午前8時、午後12時10分、5。45 pm||8:0|0:10|17:45 – GMan

+0

@GMan私の編集をチェックしてください – Xiaoy312

+0

ありがとうXiaoy312は動作します! – GMan

0
(1[0-2]|[0-9])(\.[0-5]?[0-9])?\s?([a|p]m|noon) 

証明:https://regex101.com/r/9yu6l6/2

編集:リワークたちの理解の上ではなく、それがセマンティックに基づいていないよう

+0

あなたの正規表現は、午前9時09分、午後39時99分、正午59時、午後59時と一致しますが、いずれも有効な時間値ではありません。 –

+0

編集した正規表現は、9.99 am(午前9時に一致)、90.66正午(正午6時に一致)、0.7 am(文字列全体に一致)、およびその他の無効な時刻に一致します。 –

+0

ありがとう - 私はこれを試してみると、私はどのように行くのかを教えてあげる - 入力データは正しいと思われる、私はregesを使用して、時間の出現回数を知り、 timespanオブジェクト。 – GMan

1

あなたはあなたができる元の質問で述べたようにmomentjsを使用する場合:

  • 午後LIKE「正午」を解析するために、複数の形式

で解析する

  • 使用の瞬間をあなたのロケールをカスタマイズしますdocsに記載されているmoment.updateLocalemeridiemParseisPMと指定することができます。

    次に、必要なすべての形式(例では['ha', 'h a', 'h.mma'])を指定してmoment parsing with multiple formatを使用できます。ここで

    質問に与えられた入力のための作業例:

    moment.updateLocale('en', { 
     
        meridiemParse : /[ap]\.?m?\.?|noon/i, 
     
        isPM : function (input) { 
     
        input = (input + '').toLowerCase(); 
     
        return input[0] === 'p' || input === 'noon'; 
     
        } 
     
    }); 
     
    
     
    var arr = ['8am', '12.10pm', '5.45pm', '11.30am', '12noon', '12 noon', '8 am', '7 pm.']; 
     
    
     
    for(var i=0; i<arr.length; i++){ 
     
        var m = moment(arr[i], ['ha', 'h a', 'h.mma'], true); 
     
        console.log(m.format('HH:mm'), arr[i]); 
     
    }
    <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script>

  • 1

    は、私は、これはそれがすべて:)それはあなた自身の試みのわずかな変更だん願っています。

    (?<![\d.])        # Mustn't be preceeded by a digit or . 
        (?: 
         12\s*noon      # just 12 noon 
        |  
         (?:[0-9]|0[0-9]|1[0-2])   # 12 hour clock 
         (?:\.[0-5][0-9])?    # optional minutes 
         \s*(?:[ap]m)     # mandatory am/pm 
        | 
         (?:[0-9]|0[0-9]|1[0-9]|2[0-3]) # 24 hour clock 
         (?:\.[0-5][0-9])?    # optional minutes 
        ) 
    (?![\d.]|[ap]m)       # Correct ending 
    

    Check it out here at regex101

    PS。あなたはc#とタグ付けしました。したがって、私は裏返しがOKであると仮定します。 (momentjsタグもあります)

    +0

    ありがとう - momentjsタグは、人間が読める時間を解析するためにモーメントライブラリを使用する方法があるかどうかを確認することでした。 – GMan

    関連する問題