• C++实现简单的日期正则表达式


    • 简单的日期正则表达式

    一个简单的日期解析程序,从yyyy-mm-dd格式的日期字符串中,分别获取年月日。

    先设置一个简单的正则表达式,4位数字的“年”,1-2位数字的“月”和同样1-2位数字的“日”,中间‘-’作为分隔符。程序代码:

    #include <iostream>
    #include <regex>
    
    using namespace std;
    
    int main() {
        string text = "2018-7-12";
        regex  pattern("[0-9]{4}-[0-9]{1,2}-[0-9]{1,2}");
    
        smatch results;
        if ( regex_match(text, results, pattern) ) {
            smatch::iterator it = results.begin();
            int i = 0;
            for(; it != results.end(); ++it, ++i)
                cout<<i<<": "<<*it<<endl;
        } else {
            cout << "match failed: " <<text<< endl;
        }
        return 0;
    }
    

    执行输出:

    0: 2018-7-12
    

    smatch类型是一个匹配结果字符串列表,列表中第一个元素永远是执行匹配操作的原始字符串,后续是根据表达式从原始字符串中解析出的子串。

    程序输出结果表示日期字符串与表达式匹配正确,但并没有解析出各个日期字段子串。

    如果需要解析出子串,则需要对表达式分组。

    • 表达式分组

    分组后的表达式,匹配操作才会以分组位单位输出解析出的子串。将pattern表达式修改如下:

    regex  pattern("([0-9]{4}-[0-9]{1,2}-[0-9]{1,2})");
    

    在这里,整个表达式包含在一个圆括号里,将整个表达式作为一个分组。

    执行后输出:

    0: 2018-7-12
    1: 2018-7-12
    

    下标为1的输出项,即为整个表达式分组所匹配到的内容,也就是整个日期字符串,但这还没有达到逐字段分解的目标,需要将分组细分。

    • 表达式分组细分

    将表达式改为:

    regex  pattern("([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})");
    

    其中包含了3个分组(尽管后面两个分组表达式一样,但月份和日期的取值范围并不完全相同,这里只简单设置)

    执行结果:

    0: 2018-7-12
    1: 2018
    2: 7
    3: 12
    

    终于达到了日期字段分解的目标。

    然后,日期字符串中,月份的表达方式可以是数字,也可以是字母名称,如Jan,Feb,Mar等,那么就需要在表达式中兼容多种格式的日期字符串。

    • 多个格式的月份表达式

    当前日期字符串变更名称月份,表达式中增加月份名称:

    string text = "2018-Jan-18";
    regex  pattern("([0-9]{4})-(([0-9]{1,2})|(Jan|Feb|Mar))-([0-9]{1,2})");
    

    运行结果:

    0: 2018-Jan-18
    1: 2018
    2: Jan
    3:
    4: Jan
    5: 18
    

    在这个表达式中,数字月份作为一个分组,名称月份也是一个分组,两者又合并成一个月份分组,因此匹配月份时,存在这三个分组(一个父分组包含2个子分组),运行输出结果中2-4分别是这三个分组分别对月份匹配的结果,数字月份的子分组表达式没有匹配到,因此输出空字符串。

    这样的结果并不令人满意,对于月份来说,只需输出一项即可,即对于月份匹配,两个子分组不需要单独输出,只需要表示月份的父级分组输出即可。

    通过将子分组指定为消极分组(Passive Group)即可。

    • 消极分组

    将表达式改为:

    regex  pattern("([0-9]{4})-((?:[0-9]{1,2})|(?:Jan|Feb|Mar))-([0-9]{1,2})");
    

    在分组中加上 “?:” 前缀,即表示该分组位消极分组,在此表达式中,将数字月份和名称月份的子分组都标记为消息分组,运行结果:

    1: 2018
    2: Jan
    3: 18
    
  • 相关阅读:
    c: setjmp.h 库的使用
    c:struct之匿名struct
    php:对象的数组(3)
    linuxos:gcc include 具体位置
    linuxos: LAMP环境搭建
    c: macro define 复杂的宏定义
    php:对象的数组(1)
    springboot发送邮件
    springboot 展示图片
    wsl安装centos
  • 原文地址:https://www.cnblogs.com/RioTian/p/13365972.html
Copyright © 2020-2023  润新知