之前,项目中需要解析TXT文本格式做字符分割,以空格和制表符作为分隔符分割字符串…但是文档中文本格式不规范,相当多的地方采取四个空格来替代制表符,导致分割出来的子串里面存在相当多的空白字符串…

最初的处理方案是遍历分解出来的子串,当子串为空则剔除掉…个人认为这并非长久之计…

于是思前想后,决定使用正则表达式,找出所有的连续空白字符串,然后使用一个空格替代连续的空白字符串,这样还能顺便整理不规范文档…

最开始的时候,使用boost::regex库做处理,但是很快遇到问题…boost对于国际化的支持真的不是一般的差啊…

代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void Test()
{
    std::string s = _T("一 二      三  t四t   五tt六t t七t     t八");
 
    boost::regex expr("\s+");
    s= boost::regex_replace(s,expr," ");
 
    cout < < s << endl;
}
 
// 结果为:
// ???

这个结果也太坑爹了吧…

传进去的中文最终就剩几个问号了…

于是在网上搜索了大半天,总算找到了一个解决方案,将char全部转换成wchar…

代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
//解决boost::regex中文乱码问题
std::string CTextFileDate::ReplaceString_boost(std::string strLine)
{
    // 先把string转换成wstring
    std::wstring wstrLine = s2ws(strLine);
 
    // 去掉连续的空白字符
    boost::wregex exp(_T(L"s+"));
    wstrLine = boost::regex_replace(wstrLine, exp, _T(L" "));
 
    // 将wstring转换成string
    return ws2s(wstrLine);
}
 
//Converting a WChar string to a Ansi string
std::string CTextFileDate::WChar2Ansi(LPCWSTR pwszSrc)
{
    // 获取字符串长度
    int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
    if (nLen&lt;= 0)
        return std::string("");
 
    char* pszDst = new char[nLen];
    if (NULL == pszDst)
        return std::string("");
 
    WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
    pszDst[nLen -1] = 0;
    std::string strTemp(pszDst);
    delete [] pszDst;
 
    return strTemp;
}
std::string CTextFileDate::ws2s(std::wstring&amp; inputws)
{
    return WChar2Ansi(inputws.c_str());
}
 
//Converting a Ansi string to WChar string
std::wstring CTextFileDate::Ansi2WChar(LPCSTR pszSrc, int nLen)
{
    int nSize = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pszSrc, nLen, 0, 0);
    if(nSize &lt;= 0)
        return NULL;
 
    WCHAR *pwszDst = new WCHAR[nSize+1];
    if( NULL == pwszDst) return NULL;
    MultiByteToWideChar(CP_ACP, 0,(LPCSTR)pszSrc, nLen, pwszDst, nSize);
 
    pwszDst[nSize] = 0;
    if( pwszDst[0] == 0xFEFF) // skip Oxfeff
        for(int i = 0; i &lt; nSize; i ++)
            pwszDst[i] = pwszDst[i+1];
 
    std::wstring wcharString(pwszDst);
    delete pwszDst;
 
    return wcharString;
}
std::wstring CTextFileDate::s2ws(const std::string&amp; s)
{
    return Ansi2WChar(s.c_str(),s.size());
}

使用此方法,即可将待转换的字符串转为Wchar的形式,用于boost的解析…然后解析完成后,再转换成char输出…如果不考虑性能,这倒是个完美的结局方案…哈哈…

如果考虑到性能,这种方法已然很坑爹…继续寻觅,终于找到了一个名为deelx的库…开源免费用于正则表达式…

完全采用模版的方式编写…只有一个头文件,不像boost,用个正则表达式还要包一个lib…但是该库作者承认,效率比boost慢2-5倍…

不过我觉得deelx最好的地方是支持cstring…boost因为使用了base_string,所以只支持std::string…对于VC编程的我,我最讨厌string和cstring互转了…哈哈…