前言


STL作为一个标准模版库,很多容器和算法都是很实用的,接口也相对比较友好,而且在实现上也比较轻量级。相对boost来说,要轻量得多,相对loki来说,使用的模版语法不会那么晦涩难懂,基本还是能看的,相对ATL来说,功能要更通用。

但是STL里面的string,使用过的都知道,很多常用方法没有内置,导致每每使用都会想起CString和AtlString的强大来,而混用这些字符串对象,对于一个有洁癖的程序员来说,往往是很不爽的。在工作过程中,因为有些场景不能使用CString和AtlString,针对STL的string,通过基本函数的方式,实现(积累)了一些常用用法,这里简单分享给大家。

常用方法集


大小写转换

Trim

移除子串

替换子串

StartWith & EndWith

字符串反转

容器字符串连接

字符串分割

代码


/* -------------------------------------------------------------------------
//  文件名      :  QMStlStrUtil.h
//  创建者      :  magic
//  创建时间    :  2015/9/1 17:09:32
//  功能描述    :  STL字符串通用方法(大小写,trim,替换,删除,连接,分割,反转等)
//
//  $Id: $
// -----------------------------------------------------------------------*/
#ifndef __QMSTLSTRUTIL_H__
#define __QMSTLSTRUTIL_H__

#include <string>
#include <numeric>
#include <algorithm>
// -------------------------------------------------------------------------

namespace Util
{

namespace StlStr
{

//////////////////////////////////////////////////////////////////////////
// 字符串大小写转换
//
// -------------------------------------------------------------------------
// 函数     : ToUpperT
// 功能     : 转换成大写
// 返回值   : inline void
// 参数     : std::basic_string<CharT>& s
// 附注     :
// -------------------------------------------------------------------------
template<typename CharT>
inline void ToUpper(std::basic_string<CharT>& s);

template<>
inline void ToUpper(std::basic_string<char>& s)
{
    transform(s.begin(), s.end(), s.begin(), toupper);
}

template<>
inline void ToUpper(std::basic_string<wchar_t>& s)
{
    transform(s.begin(), s.end(), s.begin(), toupper);
}

// -------------------------------------------------------------------------
// 函数     : ToUpperT
// 功能     : 转换成大写
// 返回值   : inline std::basic_string<CharT>
// 参数     : const std::basic_string<CharT>& s
// 附注     : 重载版本,参数为const
// -------------------------------------------------------------------------
template<typename CharT>
inline std::basic_string<CharT> ToUpperT(const std::basic_string<CharT>& s)
{
    std::basic_string<CharT> str(s);
    transform(str.begin(), str.end(), str.begin(), toupper);
    return str;
}

// -------------------------------------------------------------------------
// 函数     : ToLowerT
// 功能     : 转换成小写
// 返回值   : inline void
// 参数     : std::basic_string<CharT>& s
// 附注     :
// -------------------------------------------------------------------------
template<typename CharT>
inline void ToLower(std::basic_string<CharT>& s);

template<>
inline void ToLower(std::basic_string<char>& s)
{
    transform(s.begin(), s.end(), s.begin(), tolower);
}

template<>
inline void ToLower(std::basic_string<wchar_t>& s)
{
    transform(s.begin(), s.end(), s.begin(), tolower);
}

// -------------------------------------------------------------------------
// 函数     : ToLowerT
// 功能     : 转换成小写
// 返回值   : inline std::basic_string<CharT>
// 参数     : const std::basic_string<CharT>& s
// 附注     : 重载版本,参数为const
// -------------------------------------------------------------------------
template<typename CharT>
inline std::basic_string<CharT> ToLowerT(const std::basic_string<CharT>& s)
{
    std::basic_string<CharT> str(s);
    transform(str.begin(), str.end(), str.begin(), tolower);
    return str;
}

//////////////////////////////////////////////////////////////////////////
// 移除字符串前后空白符
//
//////////////////////////////////////////////////////////////////////////
// 空白符枚举
//
// "\0" - NULL
// "\t" - 制表符
// "\n" - 换行
// "\x0B" - 垂直制表符
// "\r" - 回车
// " " - 空格
//
//////////////////////////////////////////////////////////////////////////
// TrimLeft
//
template<typename CharT>
inline void TrimLeft(std::basic_string<CharT>& s);

template<>
inline void TrimLeft(std::basic_string<char>& s)
{
    const char* p = " \t\n\r\x0b";
    s.erase(0, s.find_first_not_of(p));
}

template<>
inline void TrimLeft(std::basic_string<wchar_t>& s)
{
    const wchar_t* p = L" \t\n\r\x0b";
    s.erase(0, s.find_first_not_of(p));
}

template<typename CharT>
inline void TrimLeftEx(std::basic_string<CharT>& s, const std::basic_string<CharT>& charlist);

template<>
inline void TrimLeftEx(std::basic_string<char>& s, const std::basic_string<char>& charlist)
{
    s.erase(0, s.find_first_not_of(charlist));
}

template<>
inline void TrimLeftEx(std::basic_string<wchar_t> &s, const std::basic_string<wchar_t>& charlist)
{
    s.erase(0, s.find_first_not_of(charlist));
}

//////////////////////////////////////////////////////////////////////////
// TrimRight
//
template<typename CharT>
inline void TrimRight(std::basic_string<CharT>& s);

template<>
inline void TrimRight(std::basic_string<char>& s)
{
    const char* p = " \t\n\r\x0b";
    s.erase(s.find_last_not_of(p) + 1);
}

template<>
inline void TrimRight(std::basic_string<wchar_t>& s)
{
    const wchar_t* p = L" \t\n\r\x0b";
    s.erase(s.find_last_not_of(p) + 1);
}

template<typename CharT>
inline void TrimRightEx(std::basic_string<CharT>& s, const std::basic_string<CharT>& charlist);

template<>
inline void TrimRightEx(std::basic_string<char>& s, const std::basic_string<char>& charlist)
{
    s.erase(s.find_last_not_of(charlist) + 1);
}

template<>
inline void TrimRightEx(std::basic_string<wchar_t> &s, const std::basic_string<wchar_t>& charlist)
{
    s.erase(s.find_last_not_of(charlist) + 1);
}

//////////////////////////////////////////////////////////////////////////
// Trim
//
template<typename CharT>
inline void Trim(std::basic_string<CharT>& s);

template<>
inline void Trim(std::basic_string<char>& s)
{
    const char* p = " \t\n\r\x0b";
    s.erase(0, s.find_first_not_of(p));
    s.erase(s.find_last_not_of(p) + 1);
}

template<>
inline void Trim(std::basic_string<wchar_t>& s)
{
    const wchar_t* p = L" \t\n\r\x0b";
    s.erase(0, s.find_first_not_of(p));
    s.erase(s.find_last_not_of(p) + 1);
}

template<typename CharT>
inline void TrimEx(std::basic_string<CharT>& s, const std::basic_string<CharT>& charlist);

template<>
inline void TrimEx(std::basic_string<char>& s, const std::basic_string<char>& charlist)
{
    s.erase(0, s.find_first_not_of(charlist));
    s.erase(s.find_last_not_of(charlist) + 1);
}

template<>
inline void TrimEx(std::basic_string<wchar_t> &s, const std::basic_string<wchar_t>& charlist)
{
    s.erase(0, s.find_first_not_of(charlist));
    s.erase(s.find_last_not_of(charlist) + 1);
}

//////////////////////////////////////////////////////////////////////////
// Erase 删除字符串里面的某个特殊字符
// add by magic 2015/9/7 17:43:10
//
template<typename CharT>
inline void Erase(std::basic_string<CharT>& s, const CharT& chErase);

template<>
inline void Erase(std::basic_string<char>& s, const char& chErase);

template<>
inline void Erase(std::basic_string<wchar_t>& s, const wchar_t& chErase);

template<typename CharT>
void Erase(std::basic_string<CharT>& s, const std::basic_string<CharT>& strErase);

template<>
void Erase(std::basic_string<char>& s, const std::basic_string<char>& strErase);

template<>
void Erase(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& strErase);

//////////////////////////////////////////////////////////////////////////
// Replace 替换子串为另外的子串
//
template<typename CharT>
void Replace(std::basic_string<CharT>& s, const std::basic_string<CharT>& src, const std::basic_string<CharT>& dest);

template<>
void Replace(std::basic_string<char>& s, const std::basic_string<char>& src, const std::basic_string<char>& dest);

template<>
void Replace(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& src, const std::basic_string<wchar_t>& dest);

//////////////////////////////////////////////////////////////////////////
// StartWith & EndWith
//
template<typename CharT>
inline bool StartWith(std::basic_string<CharT>& s, const std::basic_string<CharT>& head);

template<>
inline bool StartWith(std::basic_string<char>& s, const std::basic_string<char>& head)
{
    if (s.size() < head.size())
        return false;

    return (0 == s.compare(0, head.size(), head));
}

template<>
inline bool StartWith(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& head)
{
    if (s.size() < head.size())
        return false;

    return (0 == s.compare(0, head.size(), head));
}

template<typename CharT>
inline bool EndWith(std::basic_string<CharT>& s, const std::basic_string<CharT>& tail);

template<typename CharT>
inline bool EndWith(std::basic_string<char>& s, const std::basic_string<char>& tail)
{
    if (s.size() < tail.size())
        return false;

    return (0 == s.compare(s.size() - tail.size(), tail.size(), tail));
}

template<typename CharT>
inline bool EndWith(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& tail)
{
    if (s.size() < tail.size())
        return false;

    return (0 == s.compare(s.size() - tail.size(), tail.size(), tail));
}

template<typename CharT>
bool StartWithI(std::basic_string<CharT>& s, const std::basic_string<CharT>& head);

template<>
bool StartWithI(std::basic_string<char>& s, const std::basic_string<char>& head);

template<>
bool StartWithI(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& head);

template<typename CharT>
bool EndWithI(std::basic_string<CharT>& s, const std::basic_string<CharT>& tail);

template<>
bool EndWithI(std::basic_string<char>& s, const std::basic_string<char>& tail);

template<>
bool EndWithI(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& tail);

//////////////////////////////////////////////////////////////////////////
// 字符串反转
//
template<typename CharT>
inline void Reverse(std::basic_string<CharT>& s);

template<>
inline void Reverse(std::basic_string<char>& s)
{
    std::reverse(s.begin(), s.end());
}

template<>
inline void Reverse(std::basic_string<wchar_t>& s)
{
    std::reverse(s.begin(), s.end());
}

template<typename CharT>
inline std::basic_string<CharT> Reverse(const std::basic_string<CharT>& s);

template<>
inline std::basic_string<char> Reverse(const std::basic_string<char>& s)
{
    std::basic_string<char> _s(s.rbegin(), s.rend());
    return _s;
}

template<>
inline std::basic_string<wchar_t> Reverse(const std::basic_string<wchar_t>& s)
{
    std::basic_string<wchar_t> _s(s.rbegin(), s.rend());
    return _s;
}

//////////////////////////////////////////////////////////////////////////
// 容器字符串连接
//
template<typename CharT, template<typename S, typename Q = std::allocator<S> > class Container>
inline std::basic_string<CharT> Join(const Container<std::basic_string<CharT> >& c);

template<template<typename S, typename Q = std::allocator<S> > class Container>
inline std::basic_string<char> Join(const Container<std::basic_string<char> >& c)
{
    return std::accumulate(c.begin(), c.end(), std::basic_string<char>());
}

template<template<typename S, typename Q = std::allocator<S> > class Container>
inline std::basic_string<wchar_t> Join(const Container<std::basic_string<wchar_t> >& c)
{
    return std::accumulate(c.begin(), c.end(), std::basic_string<wchar_t>());
}

//////////////////////////////////////////////////////////////////////////
// 字符串分割
//
// -------------------------------------------------------------------------
// 函数     : Split
// 功能     : 分割STL标准字符串
// 返回值   : void
// 参数     : Container<std::basic_string<CharT> >& v 存放分割结果
// 参数     : const std::basic_string<CharT>& s 待分割字符串
// 参数     : const std::basic_string<CharT>& c 分割字符串
// 附注     :
// -------------------------------------------------------------------------
template<typename CharT, template<typename S, typename Q = std::allocator<S> > class Container>
void Split(Container<std::basic_string<CharT> >& v, const std::basic_string<CharT>& s, const std::basic_string<CharT>& c);

template<template<typename S, typename Q = std::allocator<S> > class Container>
void Split(Container<std::basic_string<char> >& v, const std::basic_string<char>& s, const std::basic_string<char>& c)
{
    if (0 == c.length())
        return;

    std::basic_string<char>::size_type pos1 = 0;
    std::basic_string<char>::size_type pos2 = 0;

    pos1 = 0;
    pos2 = s.find(c);
    while (std::basic_string<char>::npos != pos2)
    {
        v.push_back(s.substr(pos1, pos2 - pos1));

        pos1 = pos2 + c.size();
        pos2 = s.find(c, pos1);
    }

    if (pos1 != s.length())
    {
        v.push_back(s.substr(pos1));
    }
}

template<template<typename S, typename Q = std::allocator<S> > class Container>
void Split(Container<std::basic_string<wchar_t> >& v, const std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& c)
{
    if (0 == c.length())
        return;

    std::basic_string<wchar_t>::size_type pos1 = 0;
    std::basic_string<wchar_t>::size_type pos2 = 0;

    pos1 = 0;
    pos2 = s.find(c);
    while (std::basic_string<wchar_t>::npos != pos2)
    {
        v.push_back(s.substr(pos1, pos2 - pos1));

        pos1 = pos2 + c.size();
        pos2 = s.find(c, pos1);
    }

    if (pos1 != s.length())
    {
        v.push_back(s.substr(pos1));
    }
}

} // End Namespace StlStr

} // End Namespace Util

// -------------------------------------------------------------------------
// $Log: $

#endif /* __QMSTLSTRUTIL_H__ */
/* -------------------------------------------------------------------------
//  文件名      :  QMStlStrUtil.cpp
//  创建者      :  magic
//  创建时间    :  2015/9/1 17:09:36
//  功能描述    :
//
//  $Id: $
// -----------------------------------------------------------------------*/

#include "stdafx.h"
#include "QMStlStrUtil.h"

// -------------------------------------------------------------------------

namespace Util
{

namespace StlStr
{

template<>
inline void Erase(std::basic_string<char>& s, const char& chErase)
{
    s.erase(remove_if(s.begin(), s.end(), bind2nd(std::equal_to<char>(), chErase)), s.end());
}

template<>
inline void Erase(std::basic_string<wchar_t>& s, const wchar_t& chErase)
{
    s.erase(remove_if(s.begin(), s.end(), bind2nd(std::equal_to<wchar_t>(), chErase)), s.end());
}

template<>
void Erase(std::basic_string<char>& s, const std::basic_string<char>& strErase)
{
    std::basic_string<char>::size_type pos = 0;
    while (true)
    {
        pos = s.find(strErase, pos);
        if (std::basic_string<char>::npos == pos)
            break;

        s.erase(pos, strErase.size());
    }
}

template<>
void Erase(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& strErase)
{
    std::basic_string<wchar_t>::size_type pos = 0;
    while (true)
    {
        pos = s.find(strErase, pos);
        if (std::basic_string<wchar_t>::npos == pos)
            break;

        s.erase(pos, strErase.size());
    }
}

template<>
void Replace(std::basic_string<char>& s, const std::basic_string<char>& src, const std::basic_string<char>& dest)
{
    std::basic_string<char>::size_type pos = 0;
    while (true)
    {
        pos = s.find(src, pos);
        if (std::basic_string<char>::npos == pos)
            break;

        s.replace(pos, src.size(), dest);
        pos += src.size();
    }
}

template<>
void Replace(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& src, const std::basic_string<wchar_t>& dest)
{
    std::basic_string<wchar_t>::size_type pos = 0;
    while (true)
    {
        pos = s.find(src, pos);
        if (std::basic_string<wchar_t>::npos == pos)
            break;

        s.replace(pos, src.size(), dest);
        pos += src.size();
    }
}

template<>
bool StartWithI(std::basic_string<char>& s, const std::basic_string<char>& head)
{
    if (s.size() < head.size())
        return false;

    std::basic_string<char> _s = s.substr(0, head.size());
    std::basic_string<char> _head = head;
    ToLower(_s);
    ToLower(_head);

    return (0 == _s.compare(0, _head.size(), _head));
}

template<>
bool StartWithI(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& head)
{
    if (s.size() < head.size())
        return false;

    std::basic_string<wchar_t> _s = s.substr(0, head.size());
    std::basic_string<wchar_t> _head = head;
    ToLower(_s);
    ToLower(_head);

    return (0 == _s.compare(0, _head.size(), _head));
}

template<>
bool EndWithI(std::basic_string<char>& s, const std::basic_string<char>& tail)
{
    if (s.size() < tail.size())
        return false;

    std::basic_string<char> _s = s.substr(s.size() - tail.size(), tail.size());
    std::basic_string<char> _tail = tail;
    ToLower(_s);
    ToLower(_tail);

    return (0 == _s.compare(0, _tail.size(), _tail));
}

template<>
bool EndWithI(std::basic_string<wchar_t>& s, const std::basic_string<wchar_t>& tail)
{
    if (s.size() < tail.size())
        return false;

    std::basic_string<wchar_t> _s = s.substr(s.size() - tail.size(), tail.size());
    std::basic_string<wchar_t> _tail = tail;
    ToLower(_s);
    ToLower(_tail);

    return (0 == _s.compare(0, _tail.size(), _tail));
}

} // End Namespace StlStr

} // End Namespace Util
// -------------------------------------------------------------------------
// $Log: $

STL字符串常用方法扩展的更多相关文章

  1. python基础3 字符串常用方法

    一. 基础数据类型 总览 int:用于计算,计数,运算等. 1,2,3,100...... str:'这些内容[]'    用户少量数据的存储,便于操作. bool: True, False,两种状态 ...

  2. 2018.03.26 Python-Pandas 字符串常用方法

    import numpy as np import pandas as pd 1 #字符串常用方法 - strip s = pd.Series([' jack ','jill',' jease ',' ...

  3. day2 -- 字符串常用方法、列表、字典

    1.字符串常用方法 name = "Convict abc" count(): print(name.count("c")) # 2 find(): print ...

  4. OC中的字符串常用方法

    OC中的字符串常用方法 OC中对字符串进行操作使用了Foundation框架中的NSString类(不可变).NSMutableString类(可变). NSString 1.创建字符串 [objc] ...

  5. python 字符串常用方法

    字符串常用方法 capitalize() String.capitalize() 将字符串首字母变为大写 name = 'xiaoming' new_name = name.capitalize() ...

  6. es6 字符串的扩展和数值的扩展

    es6字符串的扩展 1. es6新增的一些方法 1.1 includes 判断是否包括在内,返回一个 true or false 1.2 statsWith 判断是否以什么开头,返回一个 true o ...

  7. Python基础二_操作字符串常用方法、字典、文件读取

    一.字符串常用方法: name.captitalize()                       #字符串首字母大写 name.center(50,'*')                   ...

  8. ES6字符串相关扩展

    变量的解构赋值 // 数组的解构赋值 let [a,b,c] = [1,2,3]; //1,2,3 let [a,b,c] = [,123,]; //undefined 123 undefined l ...

  9. ES6的新特性(4)——字符串的扩展

    字符串的扩展 ES6 加强了对 Unicode 的支持,并且扩展了字符串对象. 字符的 Unicode 表示法 JavaScript 允许采用\uxxxx形式表示一个字在\u0000~\uFFFF之间 ...

随机推荐

  1. android 原生camera——设置模块修改

    , 此篇博客是记一次客户需求修改,从上周五到现在正好一周时间,期间的各种酸爽,就不说了,还是来看大家关注的技术问题吧. 首先看下以前效果和修改后的效果: 修改前:修改后: 不知道有没有看明白,我在简单 ...

  2. 临时关闭Mac SIP系统完整性保护机制

    # 修正更新 [2016-12-27] 晚上给我笔记本安装的时候,使用user权限安装成功,mac最后是关闭sip才安装成功. $ pip install -r requirements.txt -- ...

  3. RDO Stack Exception: UnboundLocalError: local variable 'logFile' referenced before assignment

    Issue: When you install RDO stack on CentOS, you may encounter following error. Error: [root@localho ...

  4. 微信小程序基础之input输入框控件

    今天主要详写一下微信小程序中的Input输入框控件,输入框在程序中是最常见的,登录,注册,获取搜索框中的内容等等都需要,同时,还需要设置不同样式的输入框,今天的代码中都要相应的使用. input输入框 ...

  5. Android6.0 init 深入分析

    之前写过一篇关于android5.0 init的介绍,这篇博客是介绍android6.0init,之前有的代码介绍不详细.而且分析 解析init.rc那块代码也没有结合init.rc介绍. 一. ma ...

  6. J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用

    J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用   spring 中获得由spring所配置的hibernate的操作对象,然后利用此对象进行,保存,修 ...

  7. Dynamics CRM2016 Web API之Create related entities in one operation

    本篇继续来介绍两个web api的接口,一个是"Create related entities in one operation"即在一步操作中完成主实体的创建加关联实体的创建,一 ...

  8. 指令汇B新闻客户端开发(一) 新手引导页开发

    首先做开发的时候应该有一个闪屏页面和新手引导页, 我相信闪屏页面大家应该都会了,那么先看到新手引导页了. 我们可以看到这其实是一个ViewPager,我们也可以看到这是3个引导页,那么首先来看一下布局 ...

  9. 查看apk签名信息

    经常在注册开发者的时候会遇到要求填写申请应用的应用签名: 有两种很方便的方法: 1.如果没有源码或者没有打开eclipse,直接下载这个应用应用下载链接 使用截图,只要把包名输入,自动会出现签名信息. ...

  10. 向Github提交代码时遇到的一些问题

    今天分享一下我的一些小经验,那就是向github提交我们的代码.之前一直是直接使用的浏览器完成的代码的下载任务,没有使用过客户端,为了让自己在工作之前熟练使用GitHub,所以就有了下面的这篇博文了. ...