关键字
boost 正则表达式 regex_replace 自定义替换函数
背景
vs2005/boost1.48.0
多层(Multilayer)分布式系统中,持久化层和业务逻辑层分别反映数据(数据库)的物理视图和逻辑视图。客户端和服务器的交互以业务语言为基础,
从而将物理层(后台数据库)的调整对上层业务以及客户端的影响降至最小。
客户端向服务器请求数据通常会带上一个高级过滤器(通俗地讲就是where条件)。高级过滤器区别于原始过滤器,原始过滤器就是SQL Where子句,可
直接拼接到SELECT语句中;高级过滤器则不同,高级过滤器中的字段使用的是逻辑模型中的字段,例如:
"单据编号='20021000' AND 发货地 like '%北京%'"。
“单据编号”、“发货地”、“进货价”是逻辑视图名称,不是真正的字段名。因此,服务器需要将高级过滤器中的逻辑字段名查找出来转换为物理字段名。替换后的结果为:"DJBH='20021000' AND FHD like '%北京%' "
解题思路
将高级过滤器中的逻辑字段名用正则表达式提取出来,然后根据逻辑字段名查找映射表找到真实字段名进行替换。使用正则表达式提取逻辑字段名,
使用regex_replace的自定义回调函数根据逻辑字段名查找映射表找到真实字段名。
示例代码如下。示例中分别给出了使用成员函数和非成员函数作为回调函数的几种用法。
// stringmatch.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <string>
#include <boost/regex.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>
using namespace std;
string replace_callback(boost::match_results<std::string::const_iterator> match){
if( match[0].str() == "单据编号" ){
return "DJBH";
}else if( match[0].str() == "发货地" ){
return "FHD";
}else if( match[0].str() == "进货价" ){
return "JHJ";
}else{
return match[0].str();
}
}
class ClassA{
public:
string replace_callback(boost::match_results<std::string::const_iterator> match){
if( match[0].str() == "单据编号" ){
return "DJBH";
}else if( match[0].str() == "发货地" ){
return "FHD";
}else if( match[0].str() == "进货价" ){
return "JHJ";
}else{
return match[0].str();
}
}
};
int _tmain(int argc, _TCHAR* argv[])
{
std::string s = "单据编号='20021000' AND 发货地 like '%123%' AND 进货价=单据编号";
boost::regex reg("([^ |\\=|<|>]+)",boost::regex::icase);///<该正则表达式提取以空格,<,>,=等风格的单词。若在单引号中出现的<,>,=和空格也会分割,显然不合题意。欢迎熟悉正则表达式的朋友给出完整的表达式
string ret;
///<使用boost::function封装成员函数作为回调函数1
ClassA a;
boost::function<std::string (boost::match_results<std::string::const_iterator>)> function1 =
boost::bind(&ClassA::replace_callback, &a, _1);
ret=boost::regex_replace(s,reg,function1);
std::cout<<ret<<endl;
///<使用成员函数作为回调函数2
ret=boost::regex_replace(s,reg,std::bind1st(std::mem_fun(&ClassA::replace_callback), &a));
std::cout<<ret<<endl;
///<使用boost::function封装普通函数作为回调函数1
boost::function<std::string (boost::match_results<std::string::const_iterator>)> function2 =
boost::bind(&::replace_callback,_1);
ret=boost::regex_replace(s,reg,function2);
std::cout<<ret<<endl;
///<直接使用普通函数作为回调函数2
ret=boost::regex_replace(s,reg,replace_callback);
std::cout<<ret<<endl;
return 0;
}
参考资料
http://stackoverflow.com/questions/4156559/boost-custom-formatter-using-boost-bind-to-method-taking-only-one-paramerter