Visual C++中的正则表达式支持
关于C++使用正则表达式:

vs2005以下:
包含文件
#include <atlrx.h>
Unicode或英文ANSI使用CAtlRegExp<>,中文MBCS使用CAtlRegExp<CAtlRECharTraitsMB>

vs2008以上:
包含文件
#include <regex>
using namespace std;

正则表达式regex(ANSI)和wregex(Unicode)
std::regex和boost::regex使用差不多(因为std::中的很多东西本来就是源于boost::)。

vs2005中也可以安装boost库使用。vs2008以上也可以安装atl server正则库,但是已经不再维护和更新,也不建议使用。
#include <regex> 是C++TR1的内容,Visual C++ 2008 SP1就支持了,各大C++编译器厂商也都支持得很早,所以可以放心使用。

-

[修改于 4 年前 - 2015-06-15 10:47:30]

来自 软件综合
 
2015-6-11 03:31:20
acmilan(作者)
1楼
MBCS/Unicode兼容编译,可以采用basic_XXX<TCHAR>来实现,如basic_regex<TCHAR>
限定MBCS编译用不带w-开头的,如regex
限定Unicode编译用带w-开头的,如wregex
折叠评论
加载评论中,请稍候...
折叠评论
acmilan(作者)
2楼
示例程序
void CRegExTesstDlg::OnBnClickedButton1()
{
    m_rslt = L""; // 为文本框IDC_EDIT1创建的变量
   
    // 在stdafx.h中
    // #include <string>
    // #include <regex>
       
    // 导入命名空间
    using namespace std;
   
    // 需要的信息
    wstring srcstr = L"IPAddress: 192.168.1.1/255.255.255.0"; // 源字符串
    wstring regstr = L"(\\d+).(\\d+).(\\d+).(\\d+)"; // 正则表达式
    wregex reg1(regstr); // 构建正则表达式对象
   
    // 方法1:使用regex_match进行匹配
    m_rslt += L"使用regex_match匹配\r\n";
    if (regex_match(L"10.0.0.25", reg1)) // bool regex_match(字符串,正则)
        m_rslt += L"true\r\n";
    else
        m_rslt += L"false\r\n";
   
    // 方法2:使用regex_search提取并读取子串
    m_rslt += L"使用regex_search提取并匹配信息\r\n";
    wsmatch mr; // 结果
    wstring::const_iterator src_it = srcstr.begin(); // 获取起始位置
    wstring::const_iterator src_end = srcstr.end(); // 获取结束位置
    while (regex_search(src_it, src_end, mr, reg1)) { // bool regex_search(起始, 结束, &结果, 正则)
        for (int i = 0; i < (int)mr.size(); ++i) {
            // mr[i]返回wssub_match,其str()返回wstring,再c_str()返回wchar_t*
            m_rslt += mr[i].str().c_str();
            m_rslt += L"\r\n";
        }
        src_it = mr[0].second; // 迭代下一次搜索
    }
   
    // 方法3:使用wsregex_iterator搜索整个文本
    m_rslt += L"使用regex_iterator搜索整个文本\r\n";
    wsregex_iterator it(srcstr.begin(), srcstr.end(), reg1); // 正则迭代器(起始,结束,正则)
    wsregex_iterator end; // 空迭代器,表示迭代结束
    for (; it != end; ++it) { // 迭代直至结束
        // tit->返回wsmatch,其str()返回wstring,再c_str()返回wchar_t*
        m_rslt += *it->str().c_str();
        m_rslt += L"\r\n";
    }
   
    // 方法4:使用wsregex_token_iterator提取子串
    m_rslt += L"使用regex_token_iterator提取子串\r\n";
    int submat[] = { 0, 1, 2, 3, 4 }; // 子串索引(0为匹配串,1+为子串)
    // 正则token迭代器(起始,结束,正则,子项);
    wsregex_token_iterator tit(srcstr.begin(), srcstr.end(), reg1, submat);
    wsregex_token_iterator tend; // 空迭代器,表示迭代结束
    for (; tit != tend; ++tit) { // 迭代直至结束
        // it->返回wssub_match,其str()返回wstring,再c_str()返回wchar_t*
        m_rslt += tit->str().c_str();
        m_rslt += L"\r\n";
    }
   
    // 方法5:使用regex_search简单搜索
    m_rslt += L"使用regex_search简单搜索\r\n";
    regex_search(srcstr, mr, reg1); // bool regex_search(字符串, &结果, 正则)
    if (mr.size() != 0)
        m_rslt += L"mr.size() != 0\r\n";
    else
        m_rslt += L"mr.size() == 0\r\n";
   
    // 方法6:使用regex_replace替换1
    m_rslt += L"使用regex_replace替换1\r\n";
    m_rslt +=
        regex_replace(srcstr, reg1, L"$1.$2.x.$4") // wstring regex_replace(字符串, 正则, 表达式)
        .c_str();
    m_rslt += L"\r\n";
   
    // 方法7:使用regex_replace替换2
    m_rslt += L"使用regex_replace替换2\r\n";
    wstring resultstr;
    resultstr.resize(srcstr.size()); // 预留空间
    regex_replace(resultstr.begin(), srcstr.begin(), srcstr.end(), // 使用输入和输出迭代器
                  reg1, L"$1.$2.x.$4",
                  regex_constants::format_first_only); // 只替换第一个
    m_rslt += resultstr.c_str();
    m_rslt += L"\r\n";
   
    // 更新界面
    UpdateData(false);
}

运行界面:
244459


输出:
使用regex_match匹配
true
使用regex_search提取并匹配信息
192.168.1.1
192
168
1
1
255.255.255.0
255
255
255
0
使用regex_iterator搜索整个文本
1
2
使用regex_token_iterator提取子串
192.168.1.1
192
168
1
1
255.255.255.0
255
255
255
0
使用regex_search简单搜索
mr.size() != 0
使用regex_replace替换1
IPAddress: 192.168.x.1/255.255.x.0
使用regex_replace替换2
IPAddress: 192.168.x.1/255.255.255.0

(示例程序使用vs2013编写)

[修改于 4 年前 - 2015-06-11 07:40:11]

折叠评论
加载评论中,请稍候...
折叠评论
2015-6-15 10:36:13
2015-6-15 10:36:13
acmilan(作者)
3楼
今天我把上边的代码移植回Visual Studio 2010,发现regex_replace有一个地方出错了:
regextesstdlg.cpp(267): error C2784: “std::basic_string<_elem> std::tr1::regex_replace(const std::basic_string<_elem> &,const std::tr1::basic_regex<_Elem,_RxTraits> &,const std::basic_string<_elem> &,std::tr1::regex_constants::match_flag_type)”: 未能从“const wchar_t [11]”为“const std::basic_string<_elem> &”推导 模板 参数
regextesstdlg.cpp(267): error C2780: “_OutIt std::tr1::regex_replace(_OutIt,_BidIt,_BidIt,const std::tr1::basic_regex<_Elem,_RxTraits> &,const std::basic_string<_elem> &,std::tr1::regex_constants::match_flag_type)”: 应输入 6 个参数,却提供了 3 个
regextesstdlg.cpp(267): error C2228: “.c_str”的左边必须有类/结构/联合
regextesstdlg.cpp(277): error C2780: “std::basic_string<_elem> std::tr1::regex_replace(const std::basic_string<_elem> &,const std::tr1::basic_regex<_Elem,_RxTraits> &,const std::basic_string<_elem> &,std::tr1::regex_constants::match_flag_type)”: 应输入 4 个参数,却提供了 6 个
regextesstdlg.cpp(277): error C2784: “_OutTy *std::tr1::regex_replace(_OutTy (&)[_OutSize],_BidIt,_BidIt,const std::tr1::basic_regex<_Elem,_RxTraits> &,const std::basic_string<_elem> &,std::tr1::regex_constants::match_flag_type)”: 未能从“std::_String_iterator<_Elem,_Traits,_Alloc>”为“_OutTy (&)[_OutSize]”推导 模板 参数
regextesstdlg.cpp(277): error C2784: “_OutIt std::tr1::regex_replace(_OutIt,_BidIt,_BidIt,const std::tr1::basic_regex<_Elem,_RxTraits> &,const std::basic_string<_elem> &,std::tr1::regex_constants::match_flag_type)”: 未能从“const wchar_t [11]”为“const std::basic_string<_elem> &”推导 模板 参数
最后通过intellisense发现Visual Studio 2010对C++ TR1的支持并不完善,regex_replace第三个参数fmt只能使用wstring类型,不能使用wchar_t *类型。于是把
m_rslt +=
    regex_replace(srcstr, reg1, L"$1.$2.x.$4") // wstring regex_replace(字符串, 正则, 表达式)
    .c_str();
// 以及。。。
regex_replace(resultstr.begin(), srcstr.begin(), srcstr.end(), // 使用输入和输出迭代器
              reg1, L"$1.$2.x.$4",
              regex_constants::format_first_only); // 只替换第一个
改为
m_rslt +=
    regex_replace(srcstr, reg1, (wstring)L"$1.$2.x.$4") // wstring regex_replace(字符串, 正则, 表达式)
    .c_str();
// 以及。。。
regex_replace(resultstr.begin(), srcstr.begin(), srcstr.end(), // 使用输入和输出迭代器
              reg1, (wstring)L"$1.$2.x.$4",
              regex_constants::format_first_only); // 只替换第一个
问题解决。现上传VS2010版本的示例程序。
折叠评论
加载评论中,请稍候...
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

插入资源
全部
图片
视频
音频
附件
全部
未使用
已使用
正在上传
空空如也~
上传中..{{f.progress}}%
处理中..
上传失败,点击重试
{{f.name}}
空空如也~
(视频){{r.oname}}
{{selectedResourcesId.indexOf(r.rid) + 1}}
ID:{{user.uid}}
{{user.username}}
{{user.info.certsName}}
{{user.description}}
{{format("YYYY/MM/DD", user.toc)}}注册,{{fromNow(user.tlv)}}活动
{{submitted?"":"投诉"}}
请选择违规类型:
{{reason.description}}
支持的图片格式:jpg, jpeg, png