用于验证 12 小时时间的 Javascript 正则表达式

IT技术 javascript regex reactjs
2021-04-28 06:25:22

我正在尝试在 Javascript 中构建一个 12 小时的输入组件,并且我想在用户键入时实时验证格式,就像解析器验证传入的令牌一样。

我正在使用 react,所以在每次渲染中,字段值都会通过以下正则表达式传递:

const validTime = /(0[1-9])|(1[0-2]):([0-5][0-9])\s((a|p|A|P)(m|M))/;

我测试该值是否有效,如果不是,我向输入添加一个红色边框,但使用这种方法我可以写任何东西,它不会被提交,但你可以写一些类似ajsjjsdf 的东西,我正在寻找不同的东西. 允许用户仅实时键入上述正则表达式规则允许的字符。

编辑:

我正在添加一些代码...

基本上简化的输入是:

<input
  ref={(input) => {this[keyName] = input}}
  className="form-control"
  placeholder="09:00 AM"
  value={scheduleTime ? scheduleTime.value : ''}
  onChange={(ev) => this.onChangeTimeSchedule(ev, keyName)}/>

和值处理程序:

  onChangeTimeSchedule = (ev, scheduleKey) => {
    const validChar = /[0-9]|[aApPmM]|[\s\b]|:/;
    const validTime = /(0[1-9])|(1[0-2]):([0-5][0-9])\s((a|p|A|P)(m|M))/;
    const { value } = ev.target;
    if(!validTime.test(value))
      return;

    const { schedule } = this.state;
    schedule[scheduleKey] = {value, invalid: false};
    this.setState({schedule});
  };

如果我使用 validChar,它将只允许我想要的字符,但它会允许像 10:aaaM 这样的字符串。

如果我在这种情况下使用 validTime(这是我对每个渲染进行的检查,如果无效则添加红色边框),我总是返回 false,因为它除了完全匹配:10:0 是错误的,10:00 PM 是正确的。

1个回答

这是一种方法。将其设置为不区分大小写。

^(0(?:[1-9]|$)|1(?:[0-2]|$))(?:(:)(?:([0-5])(?:([0-9])(?:(\s)([ap]m?)?)?)?)?)?$

你可以得到什么:

  • 如果第 5 组长度 == 2(上午/下午),则整个时间结束。
  • 第 1 组包含部分或全部有效数据。
  • 第 2 组包含小时数。
  • 第 3 组和第 4 组包含分钟数字(连接在一起)。
  • 第 5 组包含 am/pm。

有两种方法可以使用此正则表达式。

  1. 作为有效性的测试。如果不匹配,在
    编辑框周围放一个红色框,让用户找出错误。
  2. 作为自我纠正匹配:
    • $去掉正则表达式中的最后一个,允许部分匹配。
    • 每次匹配后,将组 1(部分)写回编辑框,
      从而不允许无效条目。
      等待提交按钮,然后验证整个字符串(从开始到结束)。

格式化/解释:

 ^                             # BOS
 (                             # (1 start)
      # Hours
      (                             # (2 start)
           0 
           (?: [1-9] | $ )
        |  1 
           (?: [0-2] | $ )
      )                             # (2 end)


      # Minutes
      (?:
           :                             # ':'
           (?:

                ( [0-5] )                     # (3), Min,digit 1
                (?:
                     ( [0-9] )                     # (4), Min,digit 2
                     (?:
                          \s                            # space
                          (                             # (5 start), AM / PM
                               [ap] m?
                          )?                            # (5 end)
                     )?
                )?

           )?
      )?
 )                             # (1 end)
 $                             # EOS