C++ TR1正则库使用示例
[背景介绍]
要想在程序中使用正则表达式,首先需要有库支持.目前比较有影响的C++正则库主要有GNU Regex Library,它是glibc的一部分.另一个就是PCRE全称是Perl Compatible Regular Expressions.从名字我们可以看出PCRE库是与Perl中正则表达式相兼容的一个正则表达式库.PCRE是免费开源的库,它是由C语言实现的,这里是它的官方主页:http://www.pcre.org/ PCRE++是一个对PCRE库的C++封装.转帖一篇相关介绍的文章: http://www.linuxidc.com/Linux/2012-01/52297.htm
当然了,我们知道TR1中也包含了一个正则库,来自Boost的 regex.既然标准库中有相应的功能,自然优先使用标准库提供的功能(TR1还不是标准库,不过也是迟早的事).
现在有不少编译器已经完全实现了TR1库,这里要表扬一下微软,其在C++编译器上所做的努力和获得的进步有目共睹.VC++ 2008就已经完全实现了TR1库,VC++ 2010甚至已经迫不及待的把 tr1 名称空间合并到 std 中,急迫之情可见一斑,可惜C++ 0x遥遥无期啊.当然还有一向,继续牛着的 GNU C++编译器也完全支持 tr1 库. http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.tr1
应该说使用 tr1 库的外部条件已经完全成熟了.
[代码示例]
在VC++ 2010中建立一个 Win32 控制台工程,选中UNICODE支持.
[代码说明]
1. 创建正则表达式对象,有3中方法:
(1) 使用构造函数
std::regex_constants::syntax_option_type fl = std::regex_constants::icase; // 语法选项,可以设置使用哪种风格的正则表达式语法等.
std::wregex regExpress(regString, fl);
(2) 使用赋值运算符,缺点是不能指定语法选项,而且也比较低效.
std::wregex regExpress;
regExpress = regString;
(3) 使用assign方法.
std::wregex regExpress;
regExpress.assign(regString, fl);
构造正则对象的过称就是所谓的"编译".
2. regex_match() 和 regex_search()
regex_match()只有在整个字符串匹配正则表达式时才返回 true, 而 regex_search()在子串匹配就返回 true.
3. 匹配结果对象 std::wsmatch.
熟悉Perl正则表达式的人都知道,匹配成功后可以用 $1 $2 ... $N 来获得子串的指, tr1 regex库把匹配结果保存在一个 std::wsmatch(UNICODE) / std::smatch(ANSI) 对象中.
std::wsmatch 是一个由若干个 std::wssub_match 对象构成的数组. 而 std::wssub_match 派生自 pair.
由std::wssub_match::first保存子串的起始位置指针(其实说是迭代器比较准确一点).
由std::wssub_match::second保存子串的结束位置 +1 的指针(STL的通用原则,半开区间).
所以 [std::wssub_match::first,std::wssub_match::second) 就是子串的全部内容.
当然, std::wsmatch (match_result模版的预定义类) 提供了一些简便的方法用于访问子串:
(1) str(idx) 方法返回对应的子串的 std::string / std::wstring 对象. 只是最常用的.
(2) position(idx) 方法返回对应子串的起始偏移量.(不是指针,是相对于首字节地址或者begin()的偏移量).
(3) length(idx) 返回子串的长度.
4. 替换子串.
前面说到 std::wssub_match::first / second 保存了子串的起始/结束位置,那么我们当然可以用这个指针(迭代器)来替换文本(见代码中的 "替换1").
或者用 std::regex_replace() 也可以达到目的(见代码中的"替换2").
要想在程序中使用正则表达式,首先需要有库支持.目前比较有影响的C++正则库主要有GNU Regex Library,它是glibc的一部分.另一个就是PCRE全称是Perl Compatible Regular Expressions.从名字我们可以看出PCRE库是与Perl中正则表达式相兼容的一个正则表达式库.PCRE是免费开源的库,它是由C语言实现的,这里是它的官方主页:http://www.pcre.org/ PCRE++是一个对PCRE库的C++封装.转帖一篇相关介绍的文章: http://www.linuxidc.com/Linux/2012-01/52297.htm
当然了,我们知道TR1中也包含了一个正则库,来自Boost的 regex.既然标准库中有相应的功能,自然优先使用标准库提供的功能(TR1还不是标准库,不过也是迟早的事).
现在有不少编译器已经完全实现了TR1库,这里要表扬一下微软,其在C++编译器上所做的努力和获得的进步有目共睹.VC++ 2008就已经完全实现了TR1库,VC++ 2010甚至已经迫不及待的把 tr1 名称空间合并到 std 中,急迫之情可见一斑,可惜C++ 0x遥遥无期啊.当然还有一向,继续牛着的 GNU C++编译器也完全支持 tr1 库. http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.tr1
应该说使用 tr1 库的外部条件已经完全成熟了.
[代码示例]
在VC++ 2010中建立一个 Win32 控制台工程,选中UNICODE支持.
- #include <iostream>
- #include <string>
- #include <regex>
- int _tmain(int argc, _TCHAR* argv[])
- {
- std::locale loc("");
- std::wcout.imbue(loc);
- std::wstring text(_T("我的IP地址是:109.168.0.1."));
- std::wstring newIP(_T("127.0.0.1"));
- std::wstring regString(_T("(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)"));
- // 表达式选项 - 忽略大小写
- std::regex_constants::syntax_option_type fl = std::regex_constants::icase;
- // 编译一个正则表达式语句
- std::wregex regExpress(regString, fl);
- // 保存查找的结果
- std::wsmatch ms;
- // 判断是否全行匹配
- if(std::regex_match(text, ms, regExpress))
- {
- std::wcout<<_T("正则表达式:")<<regString<<_T("匹配:")<<text<<_T("成功.")<<std::endl;
- }
- else
- {
- std::wcout<<_T("正则表达式:")<<regString<<_T("匹配:")<<text<<_T("失败.")<<std::endl;
- }
- // 查找
- if(std::regex_search(text, ms, regExpress))
- {
- std::wcout<<_T("正则表达式:")<<regString<<_T("查找:")<<text<<_T("成功.")<<std::endl;
- for(size_t i= 0; i < ms.size(); ++i)
- {
- std::wcout<<_T("第")<<i<<_T("个结果:\"")<<ms.str(i)<<_T("\" - ");
- std::wcout<<_T("起始位置:")<<ms.position(i)<<_T("长度")<<ms.length(i)<<std::endl;
- }
- std::wcout<<std::endl;
- // 替换1
- text = text.replace(ms[0].first, ms[0].second, newIP);
- std::wcout<<_T("替换1后的文本:")<<text<<std::endl;
- }
- else
- {
- std::wcout<<_T("正则表达式:")<<regString<<_T("查找:")<<text<<_T("失败.")<<std::endl;
- }
- // 替换2
- newIP = _T("255.255.0.0");
- std::wstring newText = std::regex_replace( text, regExpress, newIP);
- std::wcout<<_T("替换2后的文本:")<<newText<<std::endl;
- // 结束
- std::wcout<<_T("按回车键结束...");
- std::wcin.get();
- return 0;
- }
1. 创建正则表达式对象,有3中方法:
(1) 使用构造函数
std::regex_constants::syntax_option_type fl = std::regex_constants::icase; // 语法选项,可以设置使用哪种风格的正则表达式语法等.
std::wregex regExpress(regString, fl);
(2) 使用赋值运算符,缺点是不能指定语法选项,而且也比较低效.
std::wregex regExpress;
regExpress = regString;
(3) 使用assign方法.
std::wregex regExpress;
regExpress.assign(regString, fl);
构造正则对象的过称就是所谓的"编译".
2. regex_match() 和 regex_search()
regex_match()只有在整个字符串匹配正则表达式时才返回 true, 而 regex_search()在子串匹配就返回 true.
3. 匹配结果对象 std::wsmatch.
熟悉Perl正则表达式的人都知道,匹配成功后可以用 $1 $2 ... $N 来获得子串的指, tr1 regex库把匹配结果保存在一个 std::wsmatch(UNICODE) / std::smatch(ANSI) 对象中.
std::wsmatch 是一个由若干个 std::wssub_match 对象构成的数组. 而 std::wssub_match 派生自 pair.
由std::wssub_match::first保存子串的起始位置指针(其实说是迭代器比较准确一点).
由std::wssub_match::second保存子串的结束位置 +1 的指针(STL的通用原则,半开区间).
所以 [std::wssub_match::first,std::wssub_match::second) 就是子串的全部内容.
当然, std::wsmatch (match_result模版的预定义类) 提供了一些简便的方法用于访问子串:
(1) str(idx) 方法返回对应的子串的 std::string / std::wstring 对象. 只是最常用的.
(2) position(idx) 方法返回对应子串的起始偏移量.(不是指针,是相对于首字节地址或者begin()的偏移量).
(3) length(idx) 返回子串的长度.
4. 替换子串.
前面说到 std::wssub_match::first / second 保存了子串的起始/结束位置,那么我们当然可以用这个指针(迭代器)来替换文本(见代码中的 "替换1").
或者用 std::regex_replace() 也可以达到目的(见代码中的"替换2").
相关推荐
杨德龙 2020-11-11
不要皱眉 2020-10-14
满地星辰 2020-09-16
梦的天空 2020-08-25
lrjnlp 2020-07-19
qidu 2020-07-05
flyingssky 2020-07-05
flyingssky 2020-06-27
RuoShangM 2020-06-17
天高任鸟飞 2020-06-13
Darklovy 2020-06-11
qidu 2020-06-08
Darklovy 2020-06-07
jyj00 2020-06-06
flyingssky 2020-06-04
山水沐光 2020-05-26
山水沐光 2020-05-25