C# 适用于人类可读时间的正则表达式-下午5时、下午5时30分、中午12时

C# 适用于人类可读时间的正则表达式-下午5时、下午5时30分、中午12时,c#,regex,parsing,momentjs,C#,Regex,Parsing,Momentjs,我试图分析的一些内容是: 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$ 证明: 编辑:基于边缘案例进行返工 证明: 编辑:基于边缘案例重新进行验证应在正则表达式之外进行,因为它不是基于语义,而是基于我们对时间的理解。虽然我们可以在正则表达式中这样做,但它会使

我试图分析的一些内容是:

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$
证明:

编辑:基于边缘案例进行返工

证明:


编辑:基于边缘案例重新进行验证应在正则表达式之外进行,因为它不是基于语义,而是基于我们对时间的理解。虽然我们可以在正则表达式中这样做,但它会使模式变得非常混乱

图案的基本形式应如下所示,简单明了:

\d{1,2}(\.\d{1,2})? ?([a|p]m|noon)
但是,我们必须添加一些命名组来隔离不同的时间段:

  • 小时数:
    (?\d{1,2})
  • 会议记录:
    (?\d{1,2})
  • 时段:
    (?[ap]m|中午)
  • 将所有内容组合在一起:
    @“(?\d{1,2})(\.(?\d{1,2}))?(?[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));
    
    var times=Regex.Matches(输入,@“(?\d{1,2})(\(?\d{1,2}))?(?[ap]m|noon)”)
    .Cast()
    //解析部分时间
    .选择(m=>new
    {
    小时=int.Parse(m.Groups[“小时”].Value),
    分钟=m.Groups[“分钟”]。成功?int.Parse(m.Groups[“分钟”].值):0,
    IsAfternoon=Regex.IsMatch(m.Groups[“period”]值,“pm | noon”),
    })
    //过滤掉无效时间
    .Where(x=>x.Hours m.Groups[“minutes”].Success | | m.Groups[“period”].Success)
    .选择(m=>new
    {
    小时=int.Parse(m.Groups[“小时”].Value),
    分钟=m.Groups[“分钟”]。成功?int.Parse(m.Groups[“分钟”].值):0,
    IsAfternoon=m.Groups[“period”].Success?Regex.IsMatch(m.Groups[“period”].Value,“pm | noon”):(bool?)null
    })
    .Dump()
    
    .Where(x=>(x.IsAfternoon!=null?x.Hours验证应该在正则表达式之外进行,因为它不是基于语义,而是基于我们对时间的理解。虽然我们可以在正则表达式中进行验证,但它会使模式变得非常混乱

    图案的基本形式应如下所示,简单明了:

    \d{1,2}(\.\d{1,2})? ?([a|p]m|noon)
    
    但是,我们必须添加一些命名组来隔离不同的时间段:

  • 小时数:
    (?\d{1,2})
  • 会议记录:
    (?\d{1,2})
  • 时段:
    (?[ap]m|中午)
  • 将所有内容组合在一起:
    @“(?\d{1,2})(\.(?\d{1,2}))?(?[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));
    
    var times=Regex.Matches(输入,@“(?\d{1,2})(\(?\d{1,2}))?(?[ap]m|noon)”)
    .Cast()
    //解析部分时间
    .选择(m=>new
    {
    小时=int.Parse(m.Groups[“小时”].Value),
    分钟=m.Groups[“分钟”]。成功?int.Parse(m.Groups[“分钟”].值):0,
    IsAfternoon=Regex.IsMatch(m.Groups[“period”]值,“pm | noon”),
    })
    //过滤掉无效时间
    .Where(x=>x.Hours m.Groups[“minutes”].Success | | m.Groups[“period”].Success)
    .选择(m=>new
    {
    小时=int.Parse(m.Groups[“小时”].Value),
    分钟=m.Groups[“分钟”]。成功?int.Parse(m.Groups[“分钟”].值):0,
    IsAfternoon=m.Groups[“period”].Success?Regex.IsMatch(m.Groups[“period”].Value,“pm | noon”):(bool?)null
    })
    .Dump()
    
    .Where(x=>(x.IsAfternoon!=null?x.Hours如果您想使用原始问题中所述的momentjs,您可以:

    • 自定义您的区域设置以像pm一样解析“中午”
    • 对多种格式使用矩分析
    您可以使用
    moment.updateScale
    指定
    meridiemParse
    isPM
    ,如中所述

    然后,您可以使用指定所需的每种格式(
    ['ha',ha',h.mma']
    ,在您的示例中)

    以下是问题中给出的输入的工作示例:

    moment.UpdateScale('en'{
    梅里迪公司:/[ap]\.?m?\.?中午/i,
    isPM:功能(输入){
    输入=(输入+“”).toLowerCase();
    返回输入[0]=“p”|输入==“中午”;
    }
    });
    var arr=['8am'、'12pm.10pm'、'5pm.45pm'、'11am.30am'、'12noon'、'12noon'、'8am'、'7pm';
    
    对于(var i=0;i如果您想使用原始问题中所述的momentjs,您可以:

    • 自定义您的区域设置以像pm一样解析“中午”
    • 对多种格式使用矩分析
    您可以使用
    moment.updateScale
    指定
    meridiemParse
    isPM
    ,如中所述

    然后,您可以使用指定所需的每种格式(
    ['ha',ha',h.mma']
    ,在您的示例中)

    以下是问题中给出的输入的工作示例:

    moment.UpdateScale('en'{
    梅里迪公司:/[ap]\.?m?\.?中午/i,
    isPM:功能(输入){
    输入=(输入+“”).toLowerCase();
    返回输入[0]=“p”|输入==“中午”;
    }
    });
    var arr=['8am'、'12pm.10pm'、'5pm.45pm'、'11am.30am'、'12noon'、'12noon'、'8am'、'7pm';
    对于(var i=0;i我希望这一切都能做到:)这是对您自己尝试的一个轻微修改

    (?<![\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
    
    (?momentjs
    标签,这让我不确定。)

    我希望这一切都可以:)这是对您自己尝试的一个轻微修改

    (?<![\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
    

    (?momentjs
    标记,这让我不确定。)

    我认为这个正则表达式解析了上面所有的情况
    [\d]{1,2}(\[\d]{1,2})?\s?(上午|下午|中午)
    你应该删除你的最后一段,这会使问题偏离主题,转而寻求正则表达式的帮助。@CaioOliveira:你的努力也会匹配上午9点9分、下午39点9分和中午99点99分,这些时间都不是有效时间。我想这个正则表达式会解析上面所有的情况
    [\d]{1,2}(\[\d]{1,2})?\s?(上午9点、下午12点)
    你应该删除你的最后一段,这会把问题转移到