std::string的一些常用操作封装

头文件定义:

/*
 * @Author: vikey
 * @Date: 2021-09-15 11:46:34
 * @LastEditTime: 2021-09-17 12:37:23
 * @LastEditors: Please set LastEditors
 * @Description: std::string的一些常用操作封装
 * @FilePath:
 * StringUtil.h
 */

#ifndef _STRING_UTIL_H_
#define _STRING_UTIL_H_

#include <string>
#include <vector>

namespace util {

    // static class 
    class StringUtil
    {
    public:
        /**
         * @description: url编码
         * @param value:待编码字符串
         * @return 函数返回:编码结果
         */
        static std::string url_encode(const std::string& value);
        /**
         * @description: url解码
         * @param value:待解码字符串
         * @return 函数返回:解码结果
         */
        static std::string url_decode(const std::string& value);
        /**
         * @description: 字符串value是否以match开头
         * @param value:原始字符串 match:匹配字符串
         * @return true 是;false 否
         */
        static bool starts_with(const std::string& value, const std::string& match);
        /**
         * @description: 字符串value是否以match结尾
         * @param value:原始字符串 match:匹配字符串
         * @return true 是;false 否
         */
        static bool ends_With(const std::string& value, const std::string& match);
        /**
         * @description: 字符串value是否包含match
         * @param value:原始字符串 match:匹配字符串
         * @return true 是;false 否
         */
        static bool contains(const std::string& value, const std::string& match);
        /**
         * @description: 字符串转大写
         * @param  value:待转换字符串
         * @return 转换后的全大写字符串
         */
        static std::string str_toupper(std::string value);
        /**
         * @description: 字符串转小写
         * @param value:待转换的字符串
         * @return 转换后的全小写字符串
         */
        static std::string str_tolower(std::string value);
        /**
         * @description: 字符串src头和尾剔除chars
         * @param src:原始字符串 chars:剔除字符串
         * @return 字符串src头和尾剔除chars的结果
         */
        static std::string& strip(std::string& src, const std::string& chars = " ");
        /**
         * @description: 字符串分割
         * @param src:待分割字符串 tokens:分割结果 delimiters:分隔符
         * @return void
         */
        static void split(const std::string& src, std::vector<std::string>& tokens,
            const std::string& delimiters = " ");
    };

} // namespace util

#endif // _STRING_UTIL_H_

代码实现:

#include "StringUtil.h"
#include <ctype.h>
#include <algorithm>

using namespace util;

// 字符"0"-"9","A"-"Z","a"-"z","-","_",".","~"都不会被编码;
// 将空格转换为加号 (+) ;
// 将非文本内容转换成"%xy"的形式,xy是两位16进制的数值;
std::string StringUtil::url_encode(const std::string& value)
{
    static auto hex_chars = "0123456789ABCDEF";

    std::string result;
    // Minimum size of result
    result.reserve(value.size());

    for (auto& chr : value)
    {
        // 可用 isalnum((unsigned char)chr) 替代 检查所传的字符是否是字母和数字
        if ((chr >= '0' && chr <= '9') || (chr >= 'A' && chr <= 'Z') ||
            (chr >= 'a' && chr <= 'z') || chr == '-' || chr == '.' ||
            chr == '_' || chr == '~')
        {
            result += chr;
        }
        else if (chr == ' ')
        {
            result += '+';
        }
        else
        {
            result += '%';
            result += hex_chars[static_cast<unsigned char>(chr) >> 4];
            result += hex_chars[static_cast<unsigned char>(chr) & 15];
        }
    }

    return result;
}

std::string StringUtil::url_decode(const std::string& value)
{
    std::string result;
    // Minimum size of result
    result.reserve(value.size() / 3 + (value.size() % 3));

    for (std::size_t i = 0; i < value.size(); ++i)
    {
        auto& chr = value[i];
        if (chr == '%' && i + 2 < value.size())
        {
            auto hex = value.substr(i + 1, 2);
            // 把参数 str 所指向的字符串根据给定的 base 转换为一个长整数
            // 类型为 long int 型
            auto decoded_chr =
                static_cast<char>(std::strtol(hex.c_str(), nullptr, 16));
            result += decoded_chr;
            i += 2;
        }
        else if (chr == '+')
        {
            result += ' ';
        }
        else
        {
            result += chr;
        }
    }

    return result;
}

bool StringUtil::starts_with(const std::string& value, const std::string& match)
{
    return ((match.size() <= value.size()) &&
        std::equal(match.begin(), match.end(), value.begin()));
}

bool StringUtil::ends_With(const std::string& value, const std::string& match)
{
    return ((match.size() <= value.size()) &&
        value.compare(value.size() - match.size(), match.size(), match) ==
        0);
}

bool StringUtil::contains(const std::string& value, const std::string& match)
{
    return (std::string::npos != value.find(match));
}

std::string StringUtil::str_toupper(std::string value)
{
    std::transform(
        value.begin(), value.end(), value.begin(),
        [](unsigned char ch) -> unsigned char { return std::toupper(ch); });
    return value;
}

std::string StringUtil::str_tolower(std::string value)
{
    std::transform(
        value.begin(), value.end(), value.begin(),
        [](unsigned char ch) -> unsigned char { return std::tolower(ch); });
    return value;
}

std::string& StringUtil::strip(std::string& src, const std::string& chars)
{
    src.erase(0, src.find_first_not_of(chars.c_str()));
    src.erase(src.find_last_not_of(chars.c_str()) + 1);
    return src;
}

void StringUtil::split(const std::string& src, std::vector<std::string>& tokens,
    const std::string& delimiters)
{
    std::string::size_type lastPos = src.find_first_not_of(delimiters, 0);
    std::string::size_type pos = src.find_first_of(delimiters, lastPos);
    while (std::string::npos != pos || std::string::npos != lastPos)
    {
        tokens.emplace_back(src.substr(lastPos, pos - lastPos));
        lastPos = src.find_first_not_of(delimiters, pos);
        pos = src.find_first_of(delimiters, lastPos);
    }
}

参考资料:
[1]. https://en.cppreference.com/w/cpp/algorithm/transform
[2]. https://stackoverflow.com/questions/26328793/how-to-split-string-with-delimiter-using-c

posted @ 2021-09-17 21:00  卡尔的思索  阅读(290)  评论(0编辑  收藏  举报