题记:一些应用中需要用到正则表达式,有的时候正则表达式中含有汉字。这时候就要用到支持unicode的正则,python是个不错的选择。但是如果代码是用C++写的,仅为了正则功能就system调用python得不偿失,而且会影响到效率。考虑到之前有在windows上成果调用boost正则的经历,所以想迁移到linux上,没有想到的是一波三折。最后成功。

1. boost的安装:

请参考

http://blog.csdn.net/wcjy07220114/article/details/7088005

重点摘录

安装boost之前最好安装python-dev icu bzip2 机子上没有在安装

现在可以安装boost了,首先要编译生成boost安装工具bjam
进入boost目录执行:
./bootstrap.sh
然后执行刚生成的
./bjam -s
HAVE_ICU=1

编译开始,大约半小时,全部编译结束。
./bjam
install --prefix=/usr

将当前目录下编译好的头文件安装到相应位置:在/usr/include下有头文件夹boost,在/usr/lib下有boost的库

 

与其不同的是,我所有的库都安装在了/usr/local下面。

2. 测试代码

  1 // please add your code here!
  2 #include <iostream>
  3 #include <stdlib.h>
  4 #include <math.h>
  5 #include<time.h>
  6 #include <set>
  7 #include <string>
  8 #include <sys/time.h>
  9 #include<locale.h>
 10 #include<boost/regex.hpp>
 11 #include </usr/local/include/iconv.h> 
 12 #include <errno.h>
 13 using namespace std;
 14 
 15 /*
 16    funcname:
 17    spec:
 18    parms:[IN]
 19          [IN]
 20          [OUT]
 21    returnValue:
 22    author liuyu, 20120528
 23 */
 24 void PrintUsage()
 25 {
 26     fprintf( stderr, "prog [IN]hzpylist_file [IN]input_file [OUT]output_file [OUT]errdmp_file\n" );
 27 }
 28 /*
 29 void PrintError(char error_text[])
 30 {
 31     fprintf(stderr,"liuyusi0121 lib run-time error...\n");     
 32     fprintf(stderr,"%s\n",error_text);
 33     fprintf(stderr,"...now exiting to system...\n");
 34     exit(1);                     
 35 
 36 }
 37 */
 38 //add your code here
 39 
 40 wstring String2Wstring(string sToMatch)  {     
 41     setlocale( LC_CTYPE, "" ); // 很重要,没有这一句,转换会失败。   
 42     int iWLen = mbstowcs( NULL, sToMatch.c_str(), sToMatch.length() ); // 计算转换后宽字符串的长度。(不包含字符串结束符)   
 43     wchar_t *lpwsz = new wchar_t[iWLen + 1];  
 44     int i = mbstowcs( lpwsz, sToMatch.c_str(), sToMatch.length() ); // 转换。(转换后的字符串有结束符)   
 45     wstring wsToMatch(lpwsz);  
 46     delete []lpwsz;  
 47     return wsToMatch;  
 48 }  
 49 //把宽字符串转换成字符串,输出使用   
 50 string Wstring2String(wstring sToMatch)  
 51 {     
 52     int iLen = wcstombs( NULL, sToMatch.c_str(), 0 ); // 计算转换后字符串的长度。(不包含字符串结束符)   
 53     char *lpsz = new char[iLen + 1];  
 54     int i = wcstombs( lpsz, sToMatch.c_str(), iLen ); // 转换。(没有结束符)   
 55     lpsz[iLen] = '\0';  
 56     string sResult(lpsz);  
 57     delete []lpsz;  
 58     return sResult;  
 59 }
 60 int toUnicode(const char *toCode,const char *fromCode,char *srcstr, char *deststr, size_t srclen,size_t &destlen)
 61 {
 62     iconv_t convertor=iconv_open(toCode,fromCode);
 63     size_t inputsize;
 64     size_t outputsize;
 65     size_t oldoutputsize;
 66     char *input, *inputold;
 67     char *output=NULL;
 68     char *outputold=NULL;
 69     int flag=0;
 70     if(convertor==iconv_t(-1))
 71     {
 72         fprintf(stderr,"convertor device initailization failed!\n");
 73         return 1;
 74     }
 75     else
 76     {
 77         inputsize=srclen;
 78         input=new char[inputsize+1];
 79         memcpy(input,srcstr,inputsize);
 80         input[inputsize]='\0';
 81         inputold=input;
 82         outputsize=inputsize*10;
 83         oldoutputsize=outputsize;
 84         output=new char[outputsize];
 85         memset(output,0,outputsize);
 86         outputold=output;
 87         size_t rc = iconv(convertor,&input,&inputsize,&output,&outputsize);
 88         if(rc==0)
 89         {
 90            memcpy(deststr,outputold,oldoutputsize-outputsize);
 91            destlen=oldoutputsize-outputsize;
 92            flag=1;
 93         }
 94         delete []inputold;
 95         delete []outputold;
 96 
 97     }
 98     iconv_close(convertor);
 99     if(flag==1)
100     {
101         return 0;
102     }
103     else
104     {
105         return 1;
106     }
107 
108 }
109 int main( int argc, char *argv[] )
110 {
111     timeval tv1, tv2;
112     gettimeofday(&tv1, NULL); 
113     if ( 1!= argc )
114     {
115         PrintUsage();
116 
117         return 1;
118     }
119 /*    
120     char *s1="刘.*?";
121     char *s2="刘禹,刘德华,刘佳佳。。。王大虎。。。" ;
122     char buf[5000]={0};
123     wchar_t *wchartemp[5000]={0};
124     size_t s1_len=strlen(s1);
125     size_t s2_len=strlen(s2);
126     size_t s3_len=0;
127     char d1[5000]={0};
128     char d2[5000]={0};
129     char d3[5000]={0};
130     size_t d1_len;
131     size_t d2_len;
132     size_t d3_len;
133     toUnicode("UCS-4//IGNORE","GBK",s1,d1,s1_len,d1_len);
134     toUnicode("UCS-4//IGNORE","GBK",s2,d2,s2_len,d2_len);
135     wchar_t *m1=(wchar_t *)d1;
136     fprintf(stdout,"%d\n",wcslen(m1));
137     wstring p1=wstring(m1);
138     fprintf(stdout,"%d\n",p1.size());
139     wchar_t *m2=(wchar_t *)d2;
140     fprintf(stdout,"%d\n",wcslen(m2));
141     wstring wtext=wstring(m2);
142     
143     std::wstring::const_iterator  it=wtext.begin();
144     std::wstring::const_iterator  end=wtext.end();
145     std::wstring::const_iterator  it1=p1.begin();
146     std::wstring::const_iterator  end1=p1.end();
147     fprintf(stdout,"%d\n",wtext.size());
148     wcout<<p1<<endl;
149     wcout<<wtext<<endl;
150 
151     boost::wregex wreg(p1,boost::regbase::icase);
152     boost::wsmatch wm;
153     vector<string> results;
154     while(boost::regex_search(it,end,wm,wreg))
155     {
156         wstring wtemp=wm[0];
157         memcpy(wchartemp,wtemp.c_str(),wtemp.size());
158         char *temp=(char *) wchartemp;
159         toUnicode("GBK//IGNORE","UCS-4",temp,buf,wtemp.size()*4,d3_len);
160         string str(temp);
161         results.push_back(str);
162         it=wm[0].second;
163     }
164     for(vector<string>::iterator it=results.begin();it!=results.end();it++)
165     {
166         printf("%s\n",(*it).c_str());
167     }
168     
169     for(int i=0;i<d1_len;i++)
170     {
171         fprintf(stdout,"%2x\t",d1[i]);
172     }
173     putchar('\n');
174     for(int i=0;i<d2_len;i++)
175     {
176         fprintf(stdout,"%2x\t",d2[i]);
177     }
178     putchar('\n');
179     toUnicode("GBK//IGNORE","UCS-4",d1,d3,d1_len,s1_len);
180     for(int i=0;i<s1_len;i++)
181     {
182         fprintf(stdout,"%2x\t",d3[i]);
183     }
184     fprintf(stdout,"%d\n",s1_len);
185     putchar('\n');
186 */    
187   
188     
189     string s="刘禹,刘德华,刘佳佳。。。王大虎。。。刘长春,xixi";
190     string t="刘[^刘]*?,";
191     wstring p=String2Wstring(t);
192     wstring ws=String2Wstring(s);
193     cout<<p.size()<<endl;
194     cout<<ws.size()<<endl;
195     boost::wregex wreg(p,boost::regbase::icase|boost::regex::perl);
196     boost::wsmatch wm;
197     vector<string> results;
198     wstring::const_iterator  it=ws.begin();
199     wstring::const_iterator  end=ws.end();
200     while(boost::regex_search(it,end,wm,wreg))
201     {
202         wstring wtemp=wm[0];
203         string temp=Wstring2String(wtemp);
204         results.push_back(temp);
205         it=wm[0].second;
206     }
207     fprintf(stdout,"输出正则匹配结果\n");
208     for(vector<string>::iterator it=results.begin();it!=results.end();it++)
209     {
210         printf("%s\n",(*it).c_str());
211     }
212     
213     gettimeofday(&tv2, NULL);
214     fprintf(stderr,"%s has finished congratulations!\n",argv[0]);
215     fprintf( stderr,"time elapsed: %.2f ms\n", (float)((tv2.tv_sec - tv1.tv_sec)*1000000+(tv2.tv_usec-tv1.tv_usec))/1000);
216     return 0;
217     
218 }
View Code

 


编译 g++ -g GetsSource.cpp /home/liuyu/MyTars/boost_1_53_0/libs/regex/src/*.cpp -o m -liconv

注意:编译的时候要链接boost源码,否则boost正则的功能函数像regex_search,regex_match等有段错误。

运行 ./m

结果liuyu: ~/Weibo/Corpora$ ./m
8
27
输出正则匹配结果
刘禹,
刘德华,
刘长春,

 注意: 我机器上的编码是GBK的,g++ 编译的时候源码文件默认是utf-8的,所以写正则模式串的时候如果直接写wstring p=L"刘.*?"等会编译不通过。建议采用我代码中的写法。

posted on 2013-05-23 09:33  finallyly  阅读(3063)  评论(0编辑  收藏  举报