`
wangminshe89
  • 浏览: 703662 次
文章分类
社区版块
存档分类
最新评论

解决Boost.Regex对中文支持不好的问题

 
阅读更多

问题的提出:

Boost.Regex作为Boost对正则表达式的实践,是C++开发中常用模式匹配工具。但在这次使用过程中发现,它他对中文的支持并不好。当我们指定/w匹配时,包含“数”或“节”等字的字符串就会出现匹配失败的问题。

解决方案:

思路:把字符都转换成宽字符,然后再匹配。
需要用到以下和宽字符有关的类:
1、wstring:
作为STL中和string相对应的类,专门用于处理宽字符串。方法和string都一样,区别是value_type是wchar_t。wstring类的对象要赋值或连接的常量字符串必须以L开头标示为宽字符。
2、wregex:
和regex相对应,专门处理宽字符的正则表达式类。同样可以使用regex_match()和regex_replace()等函数。regex_match()的结果需要放在wsmatch类的对象中。
字符和宽字符的相互转换:
1、RTL的方法
//把字符串转换成宽字符串
setlocale( LC_CTYPE, "" ); // 很重要,没有这一句,转换会失败。
int iWLen= mbstowcs( NULL, sToMatch.c_str(), sToMatch.length() ); // 计算转换后宽字符串的长度。(不包含字符串结束符)
wchar_t *lpwsz= new wchar_t[iWLen+1];
int i= mbstowcs( lpwsz, sToMatch.c_str(), sToMatch.length() ); // 转换。(转换后的字符串有结束符)
wstring wsToMatch(lpwsz);
delete []lpwsz;
//把宽字符串转换成字符串,输出使用
int iLen= wcstombs( NULL, wsm[1].str().c_str(), 0 ); // 计算转换后字符串的长度。(不包含字符串结束符)
char *lpsz= new char[iLen+1];
int i= wcstombs( lpsz, wsm[1].str().c_str(), iLen ); // 转换。(没有结束符)
lpsz[iLen] = '/0';
string sToMatch(lpsz);
delete []lpsz;
2、Win32 SDK的方法
//把字符串转换成宽字符串
int iWLen= MultiByteToWideChar( CP_ACP, 0, sToMatch.c_str(), sToMatch.size(), 0, 0 ); // 计算转换后宽字符串的长度。(不包含字符串结束符)
wchar_t *lpwsz= new wchar_t [iWLen+1];
MultiByteToWideChar( CP_ACP, 0, sToMatch.c_str(), sToMatch.size(), lpwsz, iWLen ); // 正式转换。
wsz[iWLen] = L'/0';
//把宽字符串转换成字符串,输出使用
int iLen= WideCharToMultiByte( CP_ACP, NULL, wsResult.c_str(), -1, NULL, 0, NULL, FALSE ); // 计算转换后字符串的长度。(包含字符串结束符)
char *lpsz= new char[iLen];
WideCharToMultiByte( CP_OEMCP, NULL, wsResult.c_str(), -1, lpsz, iLen, NULL, FALSE); // 正式转换。
sResult.assign( lpsz, iLen-1 ); // 对string对象进行赋值。

示例:

通过以下程序我们可以看到,对字符串做/w匹配时,某些字会引起匹配失败。通过把字符串转换成宽字符串尝试解决这个问题。

#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
using std::wstring;
#include <locale>

#include "boost/tr1/regex.hpp"
using namespace boost;

void MatchWords(string sToMatch)
{
regex rg("(//w*)");
smatch sm;
regex_match( sToMatch, sm, rg );
cout << "匹配结果:" << sm[1].str() << endl;
}

void MatchWords(wstring wsToMatch)
{
wregex wrg(L"(//w*)");
wsmatch wsm;
regex_match( wsToMatch, wsm, wrg );

int iLen= wcstombs( NULL, wsm[1].str().c_str(), 0 );
char *lpsz= new char[iLen+1];
int i= wcstombs( lpsz, wsm[1].str().c_str(), iLen );
lpsz[iLen] = '/0';

string sToMatch(lpsz);
delete []lpsz;
cout << "匹配结果:" << sToMatch << endl;
}

void main()
{
string sToMatch("数超限");
MatchWords( sToMatch );
sToMatch = "节点数目超限";
MatchWords( sToMatch );

setlocale( LC_CTYPE, "" );
int iWLen= mbstowcs( NULL, sToMatch.c_str(), sToMatch.length() );
wchar_t *lpwsz= new wchar_t[iWLen+1];
int i= mbstowcs( lpwsz, sToMatch.c_str(), sToMatch.length() );

wstring wsToMatch(lpwsz);
delete []lpwsz;
MatchWords( wsToMatch );
}


编译执行程序后输出:
匹配结果:数超限
匹配结果:
匹配结果:节点数目超限
第一行显示“数超限”匹配成功。但第二行“节点数超限”没有匹配到任何字符。只有转换成宽字符串之后才能够对“节点数超限”成功进行/w匹配


------------------------------------------------------------

其他参考

C/C++ code

#include "stdafx.h"

#include <cstdlib>

#include <stdlib.h>

#include <boost/regex.hpp>

#include <string>

#include <iostream>

using namespace std;

//using namespace boost;

boost::wregex expression(L"^//s*我+//s*[想|爱|恨|扁]+//s*你");

int main(int argc, char* argv[]) {

locale loc("Chinese-simplified");

wcout.imbue(loc);

std::wstring in = L"我我我我 爱爱爱爱爱 你";

static boost::wsmatch what;

cout << "enter test string" << endl;

//getline(cin,in);

if (boost::regex_match(in.c_str(), what, expression))

{

for (int i = 0;i < what.size();i++)

wcout << L"str :" << what[i].str() << endl;

}

else {

wcout << L"Error Input" << endl;

}

return 0;

}

============为了程序能够在VC6.0中运行 改为如下所示 ==================

boost::wregex expression(L"^//s*我+//s*[想|爱|恨|扁]+//s*你");


locale loc("Chinese-simplified");

wcout.imbue(loc);

std::wstring in = L"我我我我 爱爱爱爱爱 你";

static boost::wsmatch what;

if (boost::regex_match(in.c_str(), what, expression))
{

for (int i = 0;i < what.size();i++)
{
//string test = (LPCTSTR)what[i].str().c_str();
int iLen= WideCharToMultiByte( CP_ACP, NULL, what[i].str().c_str(), -1, NULL, 0, NULL, FALSE ); // 计算转换后字符串的长度。(包含字符串结束符)
char *lpsz= new char[iLen];
WideCharToMultiByte( CP_OEMCP, NULL, what[i].str().c_str(), -1, lpsz, iLen, NULL, FALSE);
}
}

分享到:
评论

相关推荐

    boost中文手册C++

    Boost库是C++编程语言的一个开源库集合,它提供了大量的高效、高质量的工具,用于解决各种编程问题。Boost库的设计目标是提升C++的标准库,为程序员提供更多的选择,同时也推动了C++标准的发展。Boost中文手册是面向...

    深入实践Boost:Boost程序库开发的94个秘笈(中文版)

    3. **智能指针**:Boost的smart_ptr库(包括shared_ptr、unique_ptr等)解决了原始指针可能导致的内存管理问题,提供安全、自动的资源管理。 4. **函数对象和绑定器**:Boost.Function和Boost.Bind使得函数对象和...

    boost

    Boost库是C++编程语言中的一个开源库集合,它提供了大量的高效、跨平台的工具,以增强C++的标准模板库(STL)。...无论是对标准库的扩展,还是对特定问题的解决方案,Boost都展现出了其强大的威力和灵活性。

    Boost C++ 库 简介(中文)

    11. **图论**(Graph Theory):Boost.Graph库提供了图数据结构和算法,适用于解决各种图论问题。 12. **波尔茨曼机**(Boltzmann Machines):Boost.NeuralNetworks提供了实现神经网络,包括波尔茨曼机的框架。 ...

    Boost程序库完全开发指南 第3版 中文版

    《Boost程序库完全开发指南 第3版 中文版》是一本深入探讨Boost程序库的权威指南,对于想要深入了解和利用Boost提升C++编程...通过学习本书,你将能够更高效地利用Boost库解决实际问题,写出更加优雅、高效的C++代码。

    boost库中文文档

    学习和掌握Boost库,开发者可以提升其C++编程能力,实现更高效的代码,同时也能利用Boost库提供的高级工具解决复杂问题。例如,通过使用智能指针可以更好地管理对象生命周期,避免内存泄漏;使用内存池可以优化内存...

    1.39.0版本的中文文档20090624,已完成翻译88个库

    在"boost_1_39_0_doc_20090624.chm"中,你可以找到关于1.39.0版本的所有中文文档,通过这个文件,开发者可以方便地学习和查阅Boost库的各个部分,解决在实际开发中遇到的问题。 总的来说,Boost库1.39.0版本的中文...

    VC++支持中文的正则表达式函数库

    在本案例中,"VC++支持中文的正则表达式函数库" 提供了一个专门为VC++(Visual C++)设计的正则表达式库,尤其值得注意的是,它特别优化了对中文字符的支持。 这个库由一位大陆程序员编写并开源,作者为了促进技术...

    boost库开发文档

    6. **正则表达式**:Boost.Regex库实现了C++标准库尚未提供的全面正则表达式支持。 7. **日期时间库**:Boost.DateTime提供了日期、时间和持续时间的处理,支持ISO 8601等标准。 8. **序列化库**:Boost....

    boost API 中文库

    通过阅读"boost库操作指南.chm",你可以逐步了解和掌握Boost库的每个组件,学会如何在实际项目中应用这些工具,解决C++开发中遇到的复杂问题。这个中文版的手册不仅提供理论知识,还包含实例演示和详细的API参考,是...

    Boost参考手册

    **Boost库概述** Boost是一个开源的C++库集合,它为C++标准库提供了扩展,包含了...通过深入学习这两个资源,开发者可以全面了解Boost库的功能,提升C++编程能力,并在实际项目中有效利用Boost库解决各种编程难题。

    Beyond the C++ Standard Library 中文版 超越c++标准库

    10. **正则表达式**:Boost.Regex库提供了C++标准库未包含的强大的正则表达式支持。 通过阅读《超越C++标准库》,程序员不仅可以学习到Boost库的使用,还能了解C++的前沿技术,提高自己的编程技巧。这本书深入浅出...

    boost_1_37_0 中文学习文档

    这份文档是学习和使用Boost库的关键,可以帮助开发者快速理解和应用Boost的功能,提升编程技能,解决实际问题。对于初学者,建议从基础概念和常用库开始学习,逐步深入到更复杂的功能,结合实践项目来巩固理论知识。...

    boost1.35中文帮助

    Boost库是C++编程语言中的一个开源库集合...通过查阅这份中文帮助,你可以更快地了解Boost库的功能,提升你的C++编程技能,解决实际项目中的问题。记住,持续学习和理解 Boost 的新特性对于跟上C++的发展步伐至关重要。

    编译Boost1.38

    ### 编译Boost1.38的详细步骤与解析 #### 一、下载与准备Boost库 ...通过亲自动手编译,开发者不仅可以深入了解Boost库的工作原理,还能提升对C++语言特性的理解,为解决复杂问题提供强大的工具支持。

    Beyond the C++Standard Library(boost中文版)

    - `regex`:正则表达式支持。 **9. 信号和槽机制** - **功能简介**:Boost库提供了一套信号和槽机制(`signals2`),类似于Qt库中的信号槽机制,用于实现观察者模式。 - **应用场景**:在需要实现事件驱动编程时,...

    把中文转化为Unicode

    总结来说,将汉字转化为Unicode编码在MFC环境中进行正则表达式匹配是解决中文字符问题的一种有效方式。通过理解Unicode编码的基本概念,使用MFC提供的工具进行编码转换,并结合支持Unicode的正则表达式库,我们可以...

    IIS服务器SSI(rewrite重写)插件的帮助资料

    ISAPI_Rewrite 是一款适用于IIS的功能强大的基于正则表达式的...ISAPI_Rewrite精简版完全免费,它对开发或者测试目的以及只有几个网站而且不需要分布式配置或者代理功能的小型服务器来说是一个很好的解决方案 ......

Global site tag (gtag.js) - Google Analytics