Boost::regex应用举例(一)

Boost::regex 应用举例(一)

newsuppy April, 2010

一, 安装 Boost 程序库

Boost C++ 提供了大量十分有用但是还未被加入到标准库中的程序库,我们可以从 www.boost.org 获取程序库的源代码。 Boost 中的某些库只需要 include 头文件就可以使用,另外一些则需要先行编译,如 regex 正则表达式就是一例。如何安装编译 Boost? 这里仅介绍一下在 Windows 平台,如果已经安装了 Visual C++ 9 编译器,只需要将 Boost 包解压缩后,运行根目录中的 bootstrap.bat 先行生成 bjam.exe 程序( Boost Make 系统),然后运行 bjam.exe 后,就开始编译 Boost ,完成后会生成 boost.v2 stage 目录,内有编译后的 lib 文件。接下来,我们就可以开始用 boost::regex 库了,另外 regex 也存在于 C++ TR1 Technical Report, 即下一个 C++0x 标准,也许该是 C++1x 了)中,下文介绍仍旧以 boost::regex 为准。编译时时需要链接相应的 lib 文件。

二, 文本匹配示例

需要处理的文件格式是这样的:文件中存在大量 name =”value 格式,这种格式在一行中可能存在一个,也可能是多个,其中带有下划线的斜体字为变量,需要提取出这种格式,存入到一个数据库的某个 name-value 的表中。如表 2-1 所示为示例文件的格式

NAME=”REGEX”   TYPE=”C++ Class”   DESCRIPTION=”Boost C++ Class”

ATTRIBUTE_MEMBER_1 = “regex string”

FUNCTION_MEMBER_1 = ”search”

2-1

首先是构建一个可以匹配 name =”value 格式的正则表达式,注意 name 只包含单词,字母,数字以及下划线的组合,正好与正则表达式的 ’/w’ 匹配,另外 ’=’ 的前后可以有空白字符(空格或 Tab ); value 是以双引号括起来的文本, value 本省不可以有双引号字符,那么用 "[^"]*" 来匹配,即由双引号括起来,但是不包含双引号本身的所有字符,如果只已 "*" 来表示,那么就正能匹配单个 name =”value ,遇到多个就会有问题。

boost::regex 中就构建这样一个正则表达式:

boost::regex reg("(//w+)[//s]*=[//s]*/"([^/"]*)/"");

注意 C++ 中的 ’/’ 为转义符,所有需要 ’//’ 来表示 ’/’ 。表达式中的 ’( )’ 是为了提取 name value 的,否则只能得到整个的匹配的文本。

整个的代码片段就如表 2-2

         string full_file_name = path_name_ + dbsrc_file_name_;

              ifstream src_file(full_file_name.c_str());

              string current_line;

              int line_num = 0;

              ofstream match_info_file("match_info.src" );

              if (src_file)

              {

                     while (!src_file.eof())

                     {

                            std::getline(src_file, current_line);

                            ++line_num;

                            boost::regex reg("(//w+)[//s]*=[//s]*/"([^/"]*)/"" );

                            boost::smatch src_macth_results;

 

                            std::string::const_iterator it=current_line.begin();

                            std::string::const_iterator end=current_line.end();

                            match_info_file << "line num: " << line_num << "/t" ;

                            bool match_flag = false ;

                            for (;it!=end;)

                            {

                                   if ((match_flag = boost::regex_search(it, end, src_macth_results, reg)))

                                   {

                                          for (int m_id=0; m_id<src_macth_results.size(); ++m_id)

                                          {

                                                 if (src_macth_results[m_id].matched)

                                                 {

                                                        match_info_file << "match id(matched): " << m_id << "/t" << "match string: " << src_macth_results[m_id].str() << "/n" ;

                                                 }

                                          }

                                          it = src_macth_results.suffix().first;

                                   }

                                   else

                                   {

                                          ++it;

                                   }                          

                            }

                            if (match_flag == false && current_line.length() >=1)

                                   match_info_file << "not match line: " << line_num << "/t" << current_line.c_str() << "/n" ;

                            else if (match_flag == false && current_line.length() <1)

                                   match_info_file << "not match line: " << line_num << "/t" << "Blank Line" << "/n" ;;

                     }

                     match_info_file.flush();

                     match_info_file.close();

              }

              src_file.close();

2-1

因为单行文本中的 name =”value 格式可能有多个,所以在匹配时需要用 boost::regex_search ,而 boost::regex_match 是用于完全匹配的,如果用在这里就无法匹配单行中的多个 name =”value 格式了。匹配的结果可以在 match_results 中提取出来,其中 match_results 的第 0 个是整个匹配的字符串,而其余的则是用 ’( )’ 括起来的被提取部分,对于上面的示例来说就是 name 对应于 match_results 1 个结果, value 对应于 match_results 2 个结果。

三, 推荐书籍

以上内容就是一些简要的介绍,所以再推荐一些书目。

1,  Boost 本身的 regex 文档就是很好的参考;

2,  Beyond the C++ Standard Library: An Introduction to Boost By Björn Karlsso, 2005 年的老书了,对于 boost 的简单介绍,当然包括 regex

3,  Mastering Regular Expressions, 3rd Edition By Jeffrey E. F. Friedl ,国内也有本书的中译本,余晟 译。几乎是正则表达式的最佳书籍了,介绍了各种正则表达式的方言,当然 boost::regex 也支持多种方言的正则表达式。

4,  The C++ Standard Library Extensions: A Tutorial and Reference, By Pete Becker, 主要是围绕 C++ TR1 的内容,也包含 regex ,国内有中译本,史晓明 译。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值