【问题标题】:Detect specific string structure with numeric shortform date pattern使用数字短格式日期模式检测特定的字符串结构
【发布时间】:2019-02-23 10:47:18
【问题描述】:

我正在努力编写合适的正则表达式来检测包含特定模式(版本号)和短格式日期的字符串。此字符串来自我正在构建的 Electron 应用程序中的串行端口。

根据响应的硬件,字符串有以下三种模式,但通常介于\r\n和可能的其他字符串之间:

MyHardwareName Vn.nn dd/mm/yy ⇒ (MyHardware V1.23 01/02/03)
MyHardwareName Vnn.nn dd/mm/yy ⇒ (MyHardware V12.34 01/02/03)
MyHardwareName Vn.nn dd/mm/yyyy ⇒ (MyHardware V1.23 01/ 02/2003)
MyHardwareName Vnn.nn dd/mm/yyyy ⇒ (MyHardware V12.34 01/02/2003)

到目前为止,我最接近的方法是仅检测日期并手动处理,然后查找从传输的命令开始直到 CRLF 的字符串。这不可靠,有时我会得到下一行的片段。更不用说,.split() 以多个部分返回匹配项,这并不理想。

我的尝试

运行正则表达式的数据响应

hardware -v
...(need to ignore junk here in case there is any)
MyHardware V1.23 01/02/20     (This is the only line I need)
PROCESSOR:xxxxxxxxxx
abc <n> <c> [r]     
def <n> <c> [r]     
...

正则表达式:

/([0-2][0-9]|(3)[0-1])(\/)(((0)[0-9])|((1)[0-2]))(\/)\d{0,2}/ -> 也始终捕获日期之后的行

/(hardware -v\s+)(.*)(\r\n)/ → 返回:

["hardware -v", "My ", "Hardware V1.10 06/02/15", "
↵PROCESSOR:SAMD51J19A"]

最终,我希望能够使用正则表达式拆分字符串并获得“MyHardware V1.10 06/02/15”(或上述版本之一,版本为 2 位,年份为 4 位)。

谁能建议这是否可以在一个正则表达式中完成?

【问题讨论】:

    标签: javascript regex regex-group


    【解决方案1】:

    如果您想匹配 1 次以上的单词字符(或 MyHardware 硬编码),后跟大写字母 V 和 1-2 位版本号、点和 1-2 位数字,后跟类似日期的模式,你可以使用:

    ^\w+(?:[ \t]\w+)*[ \t]+V\d{1,2}\.\d{1,2}[ \t]+(?:3[01]|[12][0-9]|0[1-9])\/(?:1[0-2]|0[1-9])\/(?:20)?[0-9]{2}
    

    Regex demo

    说明

    • ^ 字符串开始
    • \w+(?:[ \t]\w+)* 匹配一个单词 char 1+ 次,其中包含与空格或制表符匹配的可选重复部分,再匹配一个单词 char 1+ 次
    • [ \t]+V 匹配 1+ 次空格或制表符和 V
    • \d{1,2}\.\d{1,2} 匹配 1-2 位、. 和 1-2 位
    • [ \t]+ 匹配 1+ 次空格或制表符
    • (?:3[01]|[12][0-9]|0[1-9])\/(?:1[0-2]|0[1-9])\/(?:20)?[0-9]{2} 匹配类似日期的模式

    请注意,类似日期的模式不会验证日期本身,如果您不想匹配选项卡,可以将 [ \t] 替换为 pattern 中的空格。

    const regex = /^\w+(?:[ \t]\w+)*[ \t]+V\d{1,2}\.\d{1,2}[ \t]+(?:3[01]|[12][0-9]|0[1-9])\/(?:1[0-2]|0[1-9])\/(?:20)?[0-9]{2}/gm;
    const str = `hardware -v
    ...(need to ignore junk here in case there is any)
    MyHardware V1.23 01/02/20     (This is the only line I need)
    PROCESSOR:xxxxxxxxxx
    abc <n> <c> [r]
    def <n> <c> [r]
    
    
    MyHardware V1.23 01/02/03
    MyHardware V12.34 01/02/03
    MyHardware V1.23 01/02/2003
    MyHardware V12.34 01/02/2003
    My Hardware V1.23 01/02/20`;
    
    console.log(str.match(regex));

    【讨论】:

    • 太棒了,感谢您如此广泛的回复。在上述字符串上效果很好,我还意识到我忘了添加“gm”全局/匹配字符!唯一的问题是,当“MyHardware”之间可能有空格时,上述内容不匹配。示例:“我的硬件 V1.23 01/02/20”不匹配
    • @user5156141 试试这个更新版本regex101.com/r/A0OBq0/2https://regex101.com/r/A0OBq0/3
    • regex101.com/r/A0OBq0/3 完美运行。非常感谢,有时间学习一下!
    【解决方案2】:

    正则表达式1

    /(^[a-zA-Z]+)\s+(V[\d\.]+)\s+(\d+)\/(\d+)\/(\d+)/img
    

    结果

    MyHardware V1.23 01/02/03

    MyHardware V12.34 01/02/03

    MyHardware V1.23 01/02/2003

    MyHardware V12.34 01/02/2003

    正则表达式2

    (.*)(\d\d)(\d\d)$     find
    
    $1$2                  replace
    

    结果

    MyHardware V1.23 01/02/03

    MyHardware V12.34 01/02/03

    MyHardware V1.23 01/02/03

    MyHardware V12.34 01/02/03

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-27
      • 2018-08-30
      • 2016-03-02
      • 1970-01-01
      • 2016-08-04
      • 1970-01-01
      • 1970-01-01
      • 2017-04-09
      相关资源
      最近更新 更多