前言


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. PHP Misc. 函数

    PHP 杂项函数简介 我们把不属于其他类别的函数归纳到杂项函数类别. 安装 杂项函数是 PHP 核心的组成部分.无需安装即可使用这些函数. Runtime 配置 杂项函数的行为受 php.ini 文件 ...

  2. Android简易实战教程--第四十话《Spinner》

    对于Spinner控件的介绍和使用方法,可以先看之前写过的一篇博客:Spinner控件详解 本篇就基于这个知识点完成一个简单的小案例: 根据介绍,先写一个布局: <?xml version=&q ...

  3. logstash处理文件进度记录机制

    假如使用如下配置处理日志 input { file { path => "/home/vagrant/logstash/logstash-2.2.2/dbpool-logs/dev/c ...

  4. Oracle11g R2创建PASSWORD_VERIFY_FUNCTION对应密码复杂度验证函数步骤

    Oracle11g R2创建PASSWORD_VERIFY_FUNCTION对应密码复杂度验证函数步骤 运行测试环境:数据库服务器Oracle Linux 5.8 + Oracle 11g R2数据库 ...

  5. 19 子线程刷新UI runOnUiThread

    package com.example.com.fmyh; import java.io.BufferedReader; import java.io.File; import java.io.Fil ...

  6. (一三〇)UITextField的光标操作扩展

    简介 在iOS开发中,有时候需要完全自主的定义键盘,用于完整的单词输入,例如计算机应用中,需要一次性的输入sin(,在移动光标时要完整的跳过sin(,在删除时也要完整的删除,这就需要对光标的位置进行精 ...

  7. Gradle 的Daemon配置

    最近升级到Android 2.2.2之后,运行之前的项目特别卡,基本上2分钟,好的时候1分半,查询了Android官网的说明说daemon能够加快编译.于是我也尝试开启Daemon. 在Windows ...

  8. Android初级教程:shape的基本用法

    转载本文请注明出处:http://blog.csdn.net/qq_32059827/article/details/52203347   点击打开链接 在自定义进度条之前,先来学习一下shape的用 ...

  9. GCD API 记录 (三)

    本篇就不废话啦,接着上篇记录我见过或者使用过的与GCD相关的API.由于一些API使用的非常少,用过之后难免会忘记,还是记录一下比较好. 6.dispatch_group_wait 该API依然是与d ...

  10. 【UML 建模】在线UML建模工具 ProcessOn 使用详解

    总结 : -- 推荐理由 : 最近从 Windows 操作系统 转到 MAC 上, 正在看设计模式 和 重构, 找不到好用的 UML 工具, 因此在网上找了一款可以在线使用的 UML 工具, 用起来发 ...