解決Boost.Regex對中文支援不好的問題(據此解決全形數字換為半形數字)

來源:互聯網
上載者:User

解決Boost.Regex對中文支援不好的問題

 第一參考段:

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);
   }
  }

===================================

  第二參考段:

k.m.Cao
v0.1

 

問題的提出:

Boost.Regex作為Boost對Regex的實踐,是C++開發中常用模式比對工具。但在這次使用過程中發現,它他對中文的支援並不好。當我們指定\w匹配時,包含“數”或“節”等字的字串就會出現匹配失敗的問題。

解決方案:

思路:把字元都轉換成寬字元,然後再匹配。
需要用到以下和寬字元有關的類:
1、wstring:
作為STL中和string相對應的類,專門用於處理寬字元串。方法和string都一樣,區別是value_type是wchar_t。wstring類的對象要賦值或串連的常量字串必須以L開頭標示為寬字元。
2、wregex:
和regex相對應,專門處理寬字元的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匹配。

 

本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/skyremember/archive/2008/09/17/2941295.aspx

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.