【问题标题】:Regex- First instance of Time in a string正则表达式 - 字符串中时间的第一个实例
【发布时间】:2015-10-10 19:28:06
【问题描述】:

我正在尝试构建一个将第一次从字符串中提取出来的正则表达式。

问题是时间格式不规范。

以下是可能的变化。

':' with 1 hour digit before the ':' (ex. 9:00 pm)
':' with 2 hour digits before the ':' (ex. 10:00pm)
no minutes with with 1 hour digit (ex 9pm)
no minutes with with 1 hour digit (ex 10pm)

另外,“am”或“pm”之前可能有也可能没有空格

这是一个示例字符串。

7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text

我希望这个字符串返回"7:30 pm"

【问题讨论】:

    标签: regex time


    【解决方案1】:

    您没有指定要使用的工具,这里使用sed进行简单实现:

    echo '7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text' | sed 's/\([0-2]\?[0-9]\(:[0-5][0-9]\)\? *[ap]m\).*/\1/i'
    

    传奇:

    '[0-2]\?[0-9]'       match the hour (with 1 or 2 digits)
    '\(:[0-5][0-9]\)\?'  match the minutes (optional)
    ' *'                 optional spaces
    '[ap]m'              match am,pm,AM,PM (also Am,aM,pM,Pm)*
    '.*'                 match all the rest of the string
    

    上瘾:外部\(...\) 创建一组所有上述元素(反向引用),稍后用于正则表达式\1 的替换部分。 *: 最后一个/i 修饰符使正则表达式不区分大小写

    您可以将所有内容重写为标准的 perl 正则表达式:

    /(?i)[0-2]?\d(?::[0-5]\d)?\s*[ap]m/
    

    小红宝石代码:

    #!/usr/bin/env ruby
    
    input = "7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text"
    puts input[/(?i)[0-2]?\d(?::[0-5]\d)?\s*[ap]m/]
    

    【讨论】:

    • 这个解决方案似乎回答了我的问题。我错过了任何边缘情况吗?
    • 我已经修改以放宽空间限制(零个或更多)。你想使用什么语言?我们可以将正则表达式分成组并以某种特定方式格式化输出。发帖前我已经尝试了以上所有情况。
    • 现在它一直在返回,而不仅仅是第一次。我正在使用红宝石。
    • @mferg 我添加了一个 ruby​​ sn-p,variable[/regex/] 表单只返回第一个匹配项(根据需要)。
    • 感谢 Gsus。这很好用。有哪些好的正则表达式资源?
    【解决方案2】:

    试试这个正则表达式:

    (?i)\d{1,2}(?::\d{2})?\s*[ap]m
    

    解释:

    (?i)            # insensitive case
    \d{1,2}         # one or two digits
    (?:             # optional group
        :\d{2}      # the minutes
    )?              # end optional group
    \s*             # any spaces
    [ap]m           # "am" or "pm"
    

    Regex live here.

    希望对你有帮助。

    【讨论】:

    • 谢谢。这很好用。你是对的,我需要为 am AM Am pm PM Pm 设置不区分大小写。如何为此调整正则表达式?
    • 这个解决方案接受超过 59 分钟和超过 24 小时的时间。它有点不适用于现实世界
    【解决方案3】:

    您可以使用以下正则表达式:

    \d{1,2}\:?(?:\d{1,2}|)\s*[ap]m
    

    【讨论】:

      【解决方案4】:

      使用以下表达式可以实现几乎通用的解决方案:

      ([012]?\d(:[0-5]\d)?\s*(pm|am|PM|AM))
      

      它考虑捕获组,获取字符串上的所有当前时间字符串。

      在javascript中,它可能会被测试如下:

      var testTime = "7:30 pm -9 pm Lorem Ipsum is simply dummy text. 9pm-10pm Lorem Ipsum is simply dummy text";
      
      var timeRex = /([012]?\d(:[0-5]\d)?\s*(pm|am|PM|AM))/g;
      
      var firstTime = timeRex.exec(testTime)[0];
      
      console.log(firstTime);
      

      我真的相信有更好的通用解决方案。我会尝试一些更稳定的,然后在这里发布。

      【讨论】:

      • am|pm|AM|PM 明确地用于时间集中的解决方案,而不是在整个分析中应用忽略大小写。
      • 好点。唯一的另一件事是我只想在字符串中返回第一次。你如何改变这种情况下的正则表达式?编辑 - 错过了检索第一个案例的 0 索引。您将如何将其构建到表达式中?
      • 应该在这个表达式上使用一些非贪婪的技术。让我们尝试这样的事情。
      猜你喜欢
      • 1970-01-01
      • 2022-10-14
      • 1970-01-01
      • 2019-12-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-04
      相关资源
      最近更新 更多