Win32 / C++ 字符串查找与替换(忽略大小写)

CStringUtils.h

#pragma once

#include <string>
#include <vector>
#include <tchar.h>
#include <windows.h>

#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif

// 字符串转换实用工具
namespace CStringUtils
{
    // 查找字符串位置(忽略大小写)
    size_t FindNoCaseA(const std::string& strMain, const std::string& strSub, size_t offset = 0);
    size_t FindNoCaseW(const std::wstring& strMain, const std::wstring& strSub, size_t offset = 0);
    size_t FindNoCase(const _tstring& strMain, const _tstring& strSub, size_t offset = 0);

    // 替换字符串(忽略大小写)
    std::string& ReplaceNoCaseA(std::string& strMain, const std::string& strSub, const std::string& strTarget);
    std::wstring& ReplaceNoCaseW(std::wstring& strMain, const std::wstring& strSub, const std::wstring& strTarget);
    _tstring& ReplaceNoCase(_tstring& strMain, const _tstring& strSub, const _tstring& strTarget);

    // 替换字符串
    std::string& ReplaceA(std::string& strSrc, const std::string& strFind, const std::string& strReplace, bool bCase = false);
    std::wstring& ReplaceW(std::wstring& strSrc, const std::wstring& strFind, const std::wstring& strReplace, bool bCase = false);
    _tstring& Replace(_tstring& strSrc, const _tstring& strFind, const _tstring& strReplace, bool bCase = false);

    // 比较字符串
    int CompareA(const std::string& strSrc, const std::string& strDest, bool bCase = true);
    int CompareW(const std::wstring& strSrc, const std::wstring& strDest, bool bCase = true);
    int Compare(const _tstring& strSrc, const _tstring& strDest, bool bCase = true);

    // 分割字符串
    std::vector<std::string> SplitStrA(const std::string& str, const std::string& delim);
    std::vector<std::wstring> SplitStrW(const std::wstring& str, const std::wstring& delim);
    std::vector<_tstring> SplitStr(const _tstring& str, const _tstring& delim);

    // 格式化字符串
    std::string FormatA(LPCSTR pFormat, ...);
    std::wstring FormatW(LPCWSTR pFormat, ...);
    _tstring Format(LPCTSTR pFormat, ...);
}

CStringUtils.cpp

#include "CStringUtils.h"
#include <tchar.h>

namespace CStringUtils
{
    const int nStrFormatCountMax = (1024 * 1024 * 64);

    size_t FindNoCaseA(const std::string& strMain, const std::string& strSub, size_t offset/* = 0*/)
    {
        size_t findPos = std::string::npos;

        do
        {
            // 主串长度比字串小, 不需要比较
            if (strMain.size() < strSub.size())
            {
                break;
            }

            std::string strMainTmp = strMain;
            std::string strSubTmp = strSub;

            // 转换大小写
            for (auto& item : strMainTmp)
            {
                if (item >= _T('A') && item <= _T('Z')) item += 0x20;
            }

            for (auto& item : strSubTmp)
            {
                if (item >= _T('A') && item <= _T('Z')) item += 0x20;
            }

            findPos = strMainTmp.find(strSubTmp, offset);

        } while (false);

        return findPos;
    }

    size_t FindNoCaseW(const std::wstring& strMain, const std::wstring& strSub, size_t offset/* = 0*/)
    {
        size_t findPos = std::wstring::npos;

        do
        {
            // 主串长度比字串小, 不需要比较
            if (strMain.size() < strSub.size())
            {
                break;
            }

            std::wstring strMainTmp = strMain;
            std::wstring strSubTmp = strSub;

            // 转换大小写
            for (auto& item : strMainTmp)
            {
                if (item >= _T('A') && item <= _T('Z')) item += 0x20;
            }

            for (auto& item : strSubTmp)
            {
                if (item >= _T('A') && item <= _T('Z')) item += 0x20;
            }

            findPos = strMainTmp.find(strSubTmp, offset);

        } while (false);

        return findPos;
    }

    size_t FindNoCase(const _tstring& strMain, const _tstring& strSub, size_t offset/* = 0*/)
    {
#ifdef _UNICODE
        return FindNoCaseW(strMain, strSub, offset);
#else
        return FindNoCaseA(strMain, strSub, offset);
#endif
    }

    std::string& ReplaceNoCaseA(std::string& strMain, const std::string& strSub, const std::string& strTarget)
    {
        if (strSub.empty())
        {
            return strMain;
        }

        size_t nFind = 0;
        while (_tstring::npos != (nFind = FindNoCaseA(strMain, strSub, nFind)))
        {
            strMain.replace(nFind, strSub.size(), strTarget);
            nFind += strTarget.size();
        };

        return strMain;
    }

    std::wstring& ReplaceNoCaseW(std::wstring& strMain, const std::wstring& strSub, const std::wstring& strTarget)
    {
        if (strSub.empty())
        {
            return strMain;
        }

        size_t nFind = 0;
        while (_tstring::npos != (nFind = FindNoCaseW(strMain, strSub, nFind)))
        {
            strMain.replace(nFind, strSub.size(), strTarget);
            nFind += strTarget.size();
        };

        return strMain;
    }

    _tstring& ReplaceNoCase(_tstring& strMain, const _tstring& strSub, const _tstring& strTarget)
    {
#ifdef _UNICODE
        return ReplaceNoCaseW(strMain, strSub, strTarget);
#else
        return ReplaceNoCaseA(strMain, strSub, strTarget);
#endif
    }

    std::string& ReplaceA(std::string& strMain, const std::string& strSub, const std::string& strTarget, bool bCase/* = false*/)
    {
        if (strSub.empty())
        {
            return strMain;
        }

        if (bCase)
        {
            size_t nFind = 0;
            while (std::string::npos != (nFind = strMain.find(strSub, nFind)))
            {
                strMain.replace(nFind, strSub.size(), strTarget);
                nFind += strTarget.size();
            }
        }
        else
        {
            return ReplaceNoCaseA(strMain, strSub, strTarget);
        }

        return strMain;
    }

    std::wstring& ReplaceW(std::wstring& strMain, const std::wstring& strSub, const std::wstring& strTarget, bool bCase/* = false*/)
    {
        if (strSub.empty())
        {
            return strMain;
        }

        if (bCase)
        {
            size_t nFind = 0;
            while (std::wstring::npos != (nFind = strMain.find(strSub, nFind)))
            {
                strMain.replace(nFind, strSub.size(), strTarget);
                nFind += strTarget.size();
            };
        }
        else
        {
            return ReplaceNoCaseW(strMain, strSub, strTarget);
        }

        return strMain;
    }

    _tstring& Replace(_tstring& strMain, const _tstring& strSub, const _tstring& strTarget, bool bCase/* = false*/)
    {
#ifdef _UNICODE
        return ReplaceW(strMain, strSub, strTarget, bCase);
#else
        return ReplaceA(strMain, strSub, strTarget, bCase);
#endif
    }

    int CompareA(const std::string& strSrc, const std::string& strDest, bool bCase /* = true*/)
    {
        if (bCase)
        {
            return strcmp(strSrc.c_str(), strDest.c_str());
        }

        return _stricmp(strSrc.c_str(), strDest.c_str());
    }

    int CompareW(const std::wstring& strSrc, const std::wstring& strDest, bool bCase /* = true*/)
    {
        if (bCase)
        {
            return wcscmp(strSrc.c_str(), strDest.c_str());
        }

        return _wcsicmp(strSrc.c_str(), strDest.c_str());
    }

    int Compare(const _tstring& strSrc, const _tstring& strDest, bool bCase /* = true*/)
    {
#ifdef _UNICODE
        return CompareW(strSrc, strDest, bCase);
#else
        return CompareA(strSrc, strDest, bCase);
#endif
    }

    std::vector<std::string> SplitStrA(const std::string& str, const std::string& delim)
    {
        std::vector<std::string> vectorOut;
        size_t iStart = 0;
        size_t iEnd = 0;

        if (delim.empty())
        {
            vectorOut.push_back(str);
        }
        else
        {
            while ((iStart = str.find_first_not_of(delim, iEnd)) != std::string::npos)
            {
                iEnd = str.find(delim, iStart);
                vectorOut.push_back(str.substr(iStart, iEnd - iStart));
            }
        }

        return vectorOut;
    }

    std::vector<std::wstring> SplitStrW(const std::wstring& str, const std::wstring& delim)
    {
        std::vector<std::wstring> vectorOut;
        size_t iStart = 0;
        size_t iEnd = 0;

        if (delim.empty())
        {
            vectorOut.push_back(str);
        }
        else
        {
            while ((iStart = str.find_first_not_of(delim, iEnd)) != std::wstring::npos)
            {
                iEnd = str.find(delim, iStart);
                vectorOut.push_back(str.substr(iStart, iEnd - iStart));
            }
        }

        return vectorOut;
    }

    std::vector<_tstring> SplitStr(const _tstring& str, const _tstring& delim)
    {
#ifdef _UNICODE
        return SplitStrW(str, delim);
#else
        return SplitStrA(str, delim);
#endif
    }

    std::string FormatA(LPCSTR pFormat, ...)
    {
        size_t nCchCount = MAX_PATH;
        std::string strResult(nCchCount, 0);
        va_list args;

        va_start(args, pFormat);

        do
        {
            //成功则赋值字符串并终止循环
            int nSize = _vsnprintf_s(&strResult[0], nCchCount, _TRUNCATE, pFormat, args);
            if (-1 != nSize)
            {
                strResult.resize(nSize);
                break;
            }

            //缓冲大小超限终止
            if (nCchCount >= nStrFormatCountMax)
            {
                break;
            }

            //重新分配缓冲
            nCchCount *= 2;
            strResult.resize(nCchCount);

        } while (true);

        va_end(args);

        return strResult;
    }

    std::wstring FormatW(LPCWSTR pFormat, ...)
    {
        size_t nCchCount = MAX_PATH;
        std::wstring strResult(nCchCount, 0);
        va_list args;

        va_start(args, pFormat);

        do
        {
            //格式化输出字符串
            int nSize = _vsnwprintf_s(&strResult[0], nCchCount, _TRUNCATE, pFormat, args);
            if (-1 != nSize)
            {
                strResult.resize(nSize);
                break;
            }

            //缓冲大小超限终止
            if (nCchCount >= nStrFormatCountMax)
            {
                break;
            }

            //重新分配缓冲
            nCchCount *= 2;
            strResult.resize(nCchCount);

        } while (true);

        va_end(args);

        return strResult;
    }

    _tstring Format(LPCTSTR pFormat, ...)
    {
        size_t nCchCount = MAX_PATH;
        _tstring strResult(nCchCount, 0);
        va_list args;

        va_start(args, pFormat);

        do
        {
            //格式化输出字符串
            int nSize = _vsntprintf_s(&strResult[0], nCchCount, _TRUNCATE, pFormat, args);
            if (-1 != nSize)
            {
                strResult.resize(nSize);
                break;
            }

            //缓冲大小超限终止
            if (nCchCount >= nStrFormatCountMax)
            {
                break;
            }

            //重新分配缓冲
            nCchCount *= 2;
            strResult.resize(nCchCount);

        } while (true);

        va_end(args);

        return strResult;
    }
}

main.cpp

#include <iostream>
#include "CStringUtils.h"

int main()
{
	_tstring strSrc = _T("FlameCyclone");

	strSrc = CStringUtils::Replace(strSrc, _T("Lone"), _T("23424"), false);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值