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

新一篇: 内容折叠 | 旧一篇: 具有历史意义的一脚就此踩下了!

<script>function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

解决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( wsToM

解决Boost.Regex对中文支持不好的问题相关推荐

  1. CentOS cannot change locale UTF-8解决方法及设置中文支持

    CentOS cannot change locale UTF-8解决方法及设置中文支持 原文链接:https://blog.csdn.net/wave_1102/article/details/45 ...

  2. poi的autoSizeColumn方法对全角或者说中文支持不好的一个解决办法

    http://blog.csdn.net/aotian16/article/details/6270912 就是自动对齐后,获取列宽, 如果小于预期,就重新设置宽度 一小段代码 /* 自动调整宽度 * ...

  3. 解决了ConceptDraw PRO 8.0.7.0对中文支持不好的问题

    晕!再次测试还是崩溃,并且在xp里测试还是这样!继续找原因! === 最后只能用以下的方法: 要想输入汉字和标点而不崩溃的上上策只有:把想输入的打到记事本上,再copy到ConceptDraw PRO ...

  4. delphi 的 pos 函数 对中文支持不好。

    delphi 的pos函数中文下有bug. 正常情况下: pos('a','abc')  返回 1: bug示范,中文情况下: pos('胺','包装服务')=4  (⊙﹏⊙b汗): 因为 s :=' ...

  5. BBdoc、anytxt、filelocator测试效果,不知道是不是国外软件对中文支持不好,结果差距比较大

    BBdoc电脑桌面文档快速搜索软件,支持word.pdf.Excel.压缩文件.csv.wps.txt等内容关键词搜索.官网免费下载:http://www.bbdoc.cn/ 测试条件是针对相同电脑数 ...

  6. 在VB中INI文件的读写、删除(对中文支持很好)

    很多时候我们编一个程序不一定要用到注册表来保存设置(如果说一个程序没有设置就不算好程序了).INI是一个很好的选择.有人说,Savesetting是一个不错的选择,但是我了解到,不能永久的保存(起码在 ...

  7. matlab2018无法使用qcat,解决Matlab 2018a源代码的中文支持问题

    1. 问题 Matlab 2018a源代码的中文支持问题: Matlab软件要求源文件mfile采用GBK编码.但是在调用程序过程中,程序有时候必须用UTF-8编码,例如shaperead中文地图程序 ...

  8. Cygwin的中文支持(解决乱码)

    Cygwin的中文支持(解决乱码) 关键字: cygwin 中文 乱码 最近我在Cygwin中学习使用Linux的命令,但当进入Windows目录的时候看到所有中文文件都变成了"?????& ...

  9. matlab2018a字体乱码怎么办,解决Matlab 2018a源代码的中文支持问题

    1. 问题 Matlab 2018a源代码的中文支持问题: Matlab软件要求源文件mfile采用GBK编码.但是在调用程序过程中,程序有时候必须用UTF-8编码,例如shaperead中文地图程序 ...

  10. linux+wine乱码,Ubuntu下Wine乱码解决方法与中文支持

    由于这段时间安装了Ubuntu 9.04 x64的系统,也碰到了很多问题,收集起来以便方便使用 安装 wine ubuntu 官方自带了 wine , 但是推荐用 winehq 官方提供的最新版本 w ...

最新文章

  1. [JAVAEE] Thymeleaf 基本语法: 迭代循环
  2. Only the original thread that created a view hierarchy can touch its views
  3. eclipse 搜索使用。
  4. OSSIM系统的安装教程(超详细)
  5. UCOS在LPC上的移植
  6. 最全的C#图片处理帮助类ImageHelper
  7. volatile的适用场合
  8. (计算机组成原理)第五章中央处理器-第二节:指令执行过程(取指周期、间址周期、执行周期和中断周期)
  9. HiveQL:文件格式和压缩方法
  10. 系统集成资质培训 - 论文:论项目的人力资源管理
  11. 用于jqGrid获取SQL Server中数据的简单分页存储过程及sp_executesql的一点使用方法...
  12. 用阿里云香港云服务器时需要注意的方面
  13. 不同内核浏览器的差异以及浏览器渲染简介(转)
  14. SequoiaDB 网络通信三剑客(maxsocketpernode,maxsocketperthread,maxsocketthread)
  15. FZUOJ 2214 Knapsack problem 背包
  16. 为什么Qt编程出现No signal?
  17. SQL 练习题标准答案(点个赞呀)
  18. 接触【专利写作】的必备知识(包含少部分撰写技巧)
  19. B2C网站提高转化率的方法
  20. IntelliJ IDEA java开发环境

热门文章

  1. 境外支付 识别银联标识
  2. Java中哈希算法总结
  3. GEC210(S5PV210)裸机驱动之I2C
  4. nexus5x 刷机root
  5. 法国科涅克(Cognac)白兰地酒(干邑白兰地)
  6. 论提高计算机网络可靠性方法措施,提高计算机网络可靠性的相关措施论文
  7. python实现opencv学习十六:Canny边缘检测算法
  8. 365家装智选联盟卫生间怎么装修好看?卫生间实用装修技巧分享
  9. linux运行内存2g,Linux 下安装sql server 时 2G内存限制的最新(2019-08-15) 解决方案...
  10. 计算机技术在园林管理中的应用,《计算机技术在园林管理中的应用》优秀论文.doc...