C++正则表达式

regex类表示一个正则表达式,regex_match和regex_search确定一个给定字符串与一个给定的regex是否匹配,如果整个字符串与regex匹配则regex_match返回true,如果字符串中的一个子串与regex匹配,则regex_search返回true。如果它们的参数中包含smatch参数,成功匹配的相关信息存在该参数中。regex_replace将给定的字符串替换为另外一种形式。

int main()
{
    regex r1("[0-9]+");
    smatch results1;
    cout << boolalpha << regex_match("123", r1) << endl;//true
    cout << regex_match("12a", r1) << endl;//false
    string str1{ "abc12345de111" };
    if (regex_search(str1, results1, r1)) {
        cout << results1.str()<< endl;//123456
    }

    regex r2("[0-9]+[a-z]+");
    cout << boolalpha << regex_match("123", r2) << endl;//false
    cout << regex_match("12a", r2) << endl;//true
    system("pause");
}

指定regex对象的选项

当我们定义一个regex或对一个regex调用assign为其赋新值时,可以指定一些标志来影响regex如何操作,默认值为ECMAScript ,从而使regex会使用ECMA-262规范,这是很多Web浏览器使用的正则表达式语言。

    static constexpr flag_type icase      = regex_constants::icase;//匹配过程中忽略大小写
    static constexpr flag_type nosubs     = regex_constants::nosubs;//不保存匹配的子表达式
    static constexpr flag_type optimize   = regex_constants::optimize;//执行速度优先于构造速度
    static constexpr flag_type collate    = regex_constants::collate;//形如 "[a-b]" 的字符范围将对本地环境敏感
    static constexpr flag_type ECMAScript = regex_constants::ECMAScript;//使用ECMA-262指定的语法
    static constexpr flag_type basic      = regex_constants::basic;//使用POSIX基本的正则表达式语法
    static constexpr flag_type extended   = regex_constants::extended;//使用POSIX扩展的正则表达式语法
    static constexpr flag_type awk        = regex_constants::awk;//使用POSIX版本的awk语言的语法
    static constexpr flag_type grep       = regex_constants::grep;//使用POSIX版本的grep的语法
    static constexpr flag_type egrep      = regex_constants::egrep;//使用POSIX版本的egrep的语法
int main()
{
    regex r1("[a-z]+");//忽略大小写
    cout << boolalpha << regex_match("abc", r1) << endl;//true
    cout << regex_match("ABC", r1) << endl;//false

    regex r2("[a-z]+",regex::icase|regex::ECMAScript);//忽略大小写
    cout << boolalpha << regex_match("abc", r2) << endl;//true
    cout << regex_match("ABC", r2) << endl;//true
    system("pause");
}

正则表达式异常处理

如果编写的正则表达式存在错误,则在运行时标准库会抛出一个类型为regex_error的异常。

int main()
{
    try {
        regex r1("[a-z");
    }catch (regex_error e) {
        //regex_error(error_brack) : The expression contained mismatched[and].
        //code : 4
        cout <<e.what() <<endl<<"code:"<< e.code() << endl;
    }
    system("pause");
}

正则表达式类型和字符串类型

字符串类型 正则表达式类型
string regex,smatch,ssub_match,sregex_iterator
const char* regex,cmatch,csub_match,cregex_iterator
wstring wregex,wsmatch,wssub_match,wsregex_iterator
const wchar_t* wregex,wcmatch,wcsub_match,wcregex_iterator

regex迭代器

使用sregex_iterator可以获得所有匹配结果,将sregex_iterator绑定到一个字符串和一个regex对象时,sregex_iterator会调用regex_search查找第一个匹配位置,解引用迭代器时会得到最近一次搜索结果的smatch对象,当我们递增迭代器时,它调用regex_search查找下一个匹配。

sregex_iterator有两个名为prefix和suffix的成员,分别返回当前匹配之前和之后部分的ssub_match对象。

int main()
{
    string pattern("[0-9]+");
    regex r1(pattern);
    string str = "12234abc11111def2222ghj3333";
    for (sregex_iterator it(str.begin(), str.end(), r1), endIt; it != endIt; ++it) {
        cout <<it->prefix().str()<<" "<< it->str() <<" "<<it->suffix().str()<< endl;
    }
    //12234 abc11111def2222ghj3333
    //  abc 11111 def2222ghj3333
    //  def 2222 ghj3333
    //  ghj 3333
    system("pause");
}

子表达式匹配

正则表达式中通常包含一个或多个子表达式,子表达式通常用括号表示,在使用smatch保存匹配结果时,str(),str(0)表示整体正则表达式的匹配,str(1)表示第一个子表达式的匹配,str(2)表示第二个子表达式的匹配,依此类推。

smatch包含多个ssub_match元素,位置0的元素表示整体匹配结果,其余元素表示子表达式的匹配结果,如果匹配了则matched成员为true,如果整体都没匹配,则子表达式均不匹配。

int main()
{
    string pattern("([0-9]+)([a-z]+)");
    regex r(pattern);
    string str1 = "12234abc";
    smatch result1;
    if (regex_search(str1, result1, r)) {
        cout << result1.str(0) << endl;//12234abc
        cout << result1.str(1) << endl;//12234
        cout << result1.str(2) << endl;//abc
        cout << result1.str(10000) << endl;//空字符串,不会报错
        cout << boolalpha << result1[0].matched << endl;//true
        cout << result1[1].matched << endl;//true
        cout << result1[2].matched << endl;//true
        cout << result1[3].matched << endl;//false
    }

    string pattern2("([0-9]+)([a-z]+)");
    regex r2(pattern2);
    string str2 = "12234";
    smatch result2;
    regex_search(str2, result2, r2);
    cout << result2[0].matched << endl;//false
    cout << result2[1].matched << endl;//false
    cout << result2[2].matched << endl;//false

    string pattern3("([0-9]+)([a-z]+)?");//问号代表可选
    regex r3(pattern3);
    string str3 = "12234";
    smatch result3;
    regex_search(str3, result3, r3);
    cout << result3[0].matched << endl;//true
    cout << result3[1].matched << endl;//true
    cout << result3[2].matched << endl;//false
    system("pause");
}

regex_replace

regex_replace可以查找匹配正则表达式的字符串并使用其它格式来替换,符号$后跟子表达式的索引号表示一个特定的子表达式。

int main()
{
    string pattern("([0-9]{4})-([0-9]{2})-([0-9]{2})");
    regex r(pattern);
    string date = "2019-06-28 2019-06-29";
    cout << regex_replace(date, r, "$1.$2.$3") << endl;//2019.06.28 2019.06.29
    system("pause");
}

默认情况下regex_replace会将未匹配的部分原样输出,我们可以通过指定format_no_copy不输出未匹配部分。

int main()
{
    string pattern("([0-9]{4})-([0-9]{2})-([0-9]{2})");
    regex r(pattern);
    string date = "当前日期:2019-06-28";
    cout << regex_replace(date, r, "$1.$2.$3",regex_constants::format_no_copy) << endl;//2019.06.28
    system("pause");
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271