解决Boost.Regex对中文支持不好的问题 - k.m.Cao - 博客频道 - CSDN.NET

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

k.m.Cao
v0.1

 

问题的提出:

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匹配。

 

解决Boost.Regex对中文支持不好的问题的更多相关文章

  1. 【postman】postman测试API报错如下:TypeError: Failed to execute 'fetch' on 'Window': Invalid value 对中文支持不好

    使用postman测试APi的时候,因为系统需要在header部带上登录用户的信息,所以 如下: 然后测试报错如下:TypeError: Failed to execute 'fetch' on 'W ...

  2. html2pdf 中文支持问题

    系统用的是HTML2PDF V4.0.3 版本 百度后 http://blog.sina.com.cn/s/blog_6b0ce0310101fdv6.html 发现中文支持不好 还是有乱码问题 解决 ...

  3. IOS系统对fixed定位支持不好的解决方法

    问题: IOS 中所有浏览器,当页面上的输入框获得焦点时,呼出键盘. 页面底部的导航栏(position:fixed)会被键盘顶到页面的中间. 而当输入框失去焦点时,导航栏停留在页面中间,造成页面错乱 ...

  4. centos 解决中文支持问题, 如此修改可以修正eclipse 乱码问题。

    一.中文支持 安装中文语言包: yum groupinstall chinese-support 修改字符编码配置,没有这个文件就创建它: vim /etc/sysconfig/i18n 为 LANG ...

  5. 解决UnicodeEncodeError。python的docker镜像增加locale 中文支持

    用pandas的pd.read_excel()打开中文名的xlsx,报错,本来以为是xlrd的问题后来发现,是open()函数就报错: “UnicodeEncodeError: 'ascii' cod ...

  6. Centos6.5安装中文支持和中文输入法---VIM编辑器中文支持

    Centos6.5安装中文支持和中文输入法 第一步:中文支持:    在shell命令下输入: # vi  /etc/sysconfig/i18n 然后修改LANG="en_US.UTF-8 ...

  7. Centos6.5安装中文支持和中文输入法

     先来讲中文支持:    之前在网上查了不少资料,很多网友在网上都说,在shell命令下输入: # vi /etc/sysconfig/i18n 然后修改LANG="en_US.UTF-8& ...

  8. centos6编译安装zabbix3.0和中文支持整理文档

    编者按: 最近公司部分业务迁移机房,为了更方便的监控管理主机资源,决定上线zabbix监控平台.运维人员使用2.4版本的进行部署,个人在业余时间尝鲜,使用zabbix3.0进行部署,整理文档如下,仅供 ...

  9. SpringMVC解决前端传来的中文字符乱码问题

    以前乱码问题通过过滤器解决,而SpringMVC给我们提供了一个过滤器,可以在web.xml中添加以下配置 修改了xml文件需要重启服务器! <!--配置解决中文乱码过滤器--> < ...

随机推荐

  1. NEC遥控信号解码(包含完整代码)

    一.遥控器解码说明 1.遥控器的编码格式常见有两种,一种是NEC 格式,一种是RC5 格式.遥控器发出的信号,通过一个红外的接收头之后,信号被送到MCU 的一个中断引脚.通过MCU 来识别不同的时序, ...

  2. [WPF 如何] 如何向 ComboBox 添加一个空白选项

    原文:[WPF 如何] 如何向 ComboBox 添加一个空白选项 看到这个问题,你可能会蔑视一笑 : 这也能成文章? 确实,你只需要在 ItemsSource 的0位置上插入一个空白的项就是了,如: ...

  3. jdk1.6下载页面

    http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-javase6-41940 ...

  4. Android NDK 下载

    Android NDK Android NDK, Revision 10 (July 2014) Platform(32-bit target) Package Size (Bytes) MD5 Ch ...

  5. android开发的问题集(二)

    (1)子线程对UI线程操作的简便方法 子线程方法用 Looper.prepare(); 结束时候用 Looper.loop();  

  6. linux服务器WEB环境一键安装包lanmp教程之五

    在我们安装了linux服务器WEB环境一键安装包lanmp后,可能会有不少疑问还有就是使用过程中出现的问题,下面为大家总结几点比较常见的,如若还有其他疑问,可到wdlinux论坛寻找相关教程. 1.增 ...

  7. 微信小程序 app.json 配置

    我们使用app.json文件来对微信小程序进行全局配置,决定页面文件的路径.窗口表现.设置网络超时时间.设置多 tab 等. 以下是一个包含了所有配置选项的简单配置app.json : { " ...

  8. Connect the Cities(prime)

    Connect the Cities Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other) ...

  9. IDE idea 更换项目的JDK步骤

    1.如图:

  10. 从头开始-06.C语言中预处理指令

    预处理指令 不带参数的宏定义: 格式: #define 宏名 值 作用:提高代码的可读性 在程序编译前把所有出现宏名标示的位置都替换为定义宏的时候,宏名后面的值 带参数的宏定义 格式 #define ...