美文网首页
boost::regex库进行正则表达式替换

boost::regex库进行正则表达式替换

作者: FredricZhu | 来源:发表于2021-04-18 10:11 被阅读0次

C++的boost::regex库提供了3种正则表达式匹配类型。
perl
posix::basic
posix::extended
平时我们用posix::extended就可以了。
没错,C++就是这样,别人有的功能我们要有,别人没有的我们也要有,所以这个语言的语法部分会变得比较庞杂。
本节讲下,如何使用boost::regex库实现正则表达式匹配部分的替换。
非必要不要使用正则表达式。直接substr会让代码更清晰。

代码如下,需要注意的事项已经在注释中列出。
CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
project(lexical_cast)

add_definitions(-std=c++14)

include_directories("/usr/local/include")
link_directories("/usr/local/lib")
file( GLOB APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
foreach( sourcefile ${APP_SOURCES} )
    file(RELATIVE_PATH filename ${CMAKE_CURRENT_SOURCE_DIR} ${sourcefile})
    string(REPLACE ".cpp" "" file ${filename})
    add_executable(${file} ${sourcefile})
    target_link_libraries(${file} boost_filesystem boost_regex boost_thread boost_system boost_serialization pthread boost_chrono)
endforeach( sourcefile ${APP_SOURCES} )

main.cpp

#include <boost/regex.hpp>

#include <iostream>

int main(int argc, char* argv[]) {
    std::cout << "Availables regex syntaxes: \n" <<
        "\t[0] Perl\n" <<
        "\t[1] Perl case insensitive\n" <<
        "\t[2] Posix extended\n" <<
        "\t[3] Posix extended case insensitive\n" <<
        "\t[4] Posix basic\n" <<
        "\t[5] Posix basic case insensitive\n" <<
        "Choose regex syntax: ";
    
    boost::regex::flag_type flag;

    switch(std::cin.get()) {
        case '0':
            flag = boost::regex::perl;
            break;
        case '1':
            flag = boost::regex::perl | boost::regex::icase;
            break;
        case '2':
            flag = boost::regex::extended;
            break;
        case '3':
            flag = boost::regex::extended | boost::regex::icase;
            break;
        case '4':
            flag = boost::regex::basic;
            break;
        case '5':
            flag = boost::regex::basic | boost::regex::icase;
            break;
        default:
            std::cout << "Incorrect number of regex syntax. Exiting...\n";
            return -1;
    }

    // 禁止抛出异常,原因和上节一样
    flag |= boost::regex::no_except;
   
    // 清空std::cin
    std::cin.ignore();
    std::cin.clear();

    std::string regex, str, replace_string;

    do {
        std::cout << "\nInput regex: ";
        // 未获取到正则表达式,返回
        if(!std::getline(std::cin, regex) || regex.empty()) {
            return 0;
        }
        // 若flag标志位中不设置禁止异常,构造函数可能抛出异常,
        // 不方便测试和维护
        const boost::regex e(regex, flag);
        if(e.status()) {
            std::cout << "Incorrect regex pattern!\n";
            continue;
        }

        std::cout << "String to match: ";
        while(std::getline(std::cin, str) && !str.empty()) {
            // 这个返回值值得详细讲解下,直接看源码
            // 这是smatch的定义,smatch被定义为match_results
            // typedef match_results<std::string::const_iterator> smatch;
            //
            // match_results中有这样一个结构来保存结果,这里的BidiIterator可以理解为std::string::const_iterator
            // 更简单一点的理解是 iterator<const char*>
            // 所以说如下定义可以替换为 std::vector<sub_match<iterator<const char*> > >
            // typedef std::vector<sub_match<BidiIterator>, Allocator> vector_type;
            // 
            // 再往下看sub_match的定义
            // struct sub_match : public std::pair<BidiIterator, BidiIterator>
            // 这就很简单了,
            // 整体的结构就是 std::vector<std::pair<iterator<const char*>, iterator<const char*> > >
            // 其中第一层迭代器代表 若干个字符串, 例如 regex是 he(.*)ow(.*)ld,待匹配串是helloworld,
            // 那么第一层迭代器指向{"ll", "or"} 这个数组中的元素
            // 第二层迭代器是一个pair,pair的first是数组每个元素的 起始字母,pair的second是数组每个元素的结束字母
            // 例如,对于 ll来说,first指向第一个l, second指向第二个l之后
            // 
            // 有一个特例,boost C++和java一样,第一个返回的第一个匹配串是原串,例如上例的第一个匹配串是 helloworld
            boost::smatch results;
            bool matched = regex_search(str, results, e);
            if(matched) {
                std::cout << "MATCH: ";
                // 匹配成功之后打印出所有匹配串,以,分割
                std::copy(
                        results.begin() + 1,
                        results.end(),
                        std::ostream_iterator<std::string>(std::cout, ", ")
                );

                // 请输入替换字符
                std::cout << "\nReplace pattern: ";
                if(std::getline(std::cin, replace_string) && !replace_string.empty()) {
                    // 开始做替换
                    std::string res = "";
                    for(auto it = results.begin() + 1, it_end = results.end(); it != it_end; ++it) {
                        res = str.replace(it->begin(), it->end(), replace_string);
                    }
                    std::cout << "RESULT: " << str << std::endl;
                }else {
                    std::cin.ignore();
                    std::cin.clear();
                }
            }else {
                std::cout << "DOES NOT MATCH";
            }

            std::cout << "\n String to match: ";
        }
    } while(1);

    return 0;
}

程序输出如下,


图片.png

相关文章

  • boost::regex库进行正则表达式替换

    C++的boost::regex库提供了3种正则表达式匹配类型。perlposix::basicposix::ex...

  • 使用boost::regex库进行正则表达式匹配

    代码非常简单,但是C++的regex库功能非常全面,提供了perl格式正则表达式,posix extend正则表达...

  • Swift 4.0 正则的使用

    一、正则表达式的用途(搜索和替换) 1.1.正则表达式(regular expression,简称regex)是一...

  • 半小时学会正则表达式(上)

    正则表达式(Regular Expression)在代码中常常简写为regex。正则表达式通常被用来检索、替换那些...

  • boost 正则表达式 regex

    环境安装 如果在引用boost regex出现连接错误,但是引用其他的库却没有这个错误,这是因为对于boost来说...

  • Java 正则表达式之Pattern和Matcher

    Java的regex库 java里预留了一个regex库,方便于我们在Java里操作正则表达式,或者用它来匹配字符...

  • C# 正则表达式基础

    正则表达式 Regex类 元字符 正则表达式通常用来检查,检索,替换符合某个格式的文本 元字符: 正则表达式语言由...

  • 正则表达式

    正则表达式又称规则表达式,英文:Regular Expression,简写为regex,通常用来检索、替换哪些符合...

  • 正则表达式

    Regex 正则表达式通常用来检查,检索,替换符合某个格式的文本 元字符: 正则表达式语言由两种基本字符组成. 原...

  • 09.正则表达式re-1.正则表达式

    1、正则表达式概述 正则表达式(英语:Regular Expression,在代码中常简写为regex、regex...

网友评论

      本文标题:boost::regex库进行正则表达式替换

      本文链接:https://www.haomeiwen.com/subject/hdbmlltx.html