C++ 有没有办法替换字符串中的多个标记

时间:2021-04-28 15:40:38

标签: c++

我正在开发一个简单的终端 shell,我想知道是否有办法用其他值替换字符串中的多个变量标记。

给定类似 PATH = $PATH:$CWD 的东西,这将转化为 PATH = /usr/bin:/usr

我当前的代码只能处理一个字符串中的一个变量。仅当标记后跟非字母数字字符时才能替换该变量。

string varInterp(string &token)
{
    int startIndex = -1, endIndex = -1;
    for (int i = 0; i < token.size(); i++)
    {
        if (token[i] == '$')
        {
            startIndex = i;
            int j = i+1;
            while (isalnum(token[j]) && j < token.size())
            {
                endIndex = j;
                j++;
            }
            if (j == token.size())
                endIndex = -1;
        }
    }
    if (startIndex != -1 && endIndex != -1)
    {
        int varLen = endIndex - startIndex;
        string varName = token.substr(startIndex+1,varLen);
        string varVal = globalVars.getVal(varName);
        token.replace(startIndex,varLen+1,varVal);
    }
    return token;
}

2 个答案:

答案 0 :(得分:0)

一种可能的解决方案是如何解析大字符串,就像在简单的计算器中一样使用堆栈。您只需将所有字符串逐步推入堆栈,将其拆分为有意义的小块。 这段代码并不完美,我只是在这里展示以下想法。

#include <stack>
#include <string>
#include <iostream>
#include <map>


std::string parser(std::string str)
{
    std::map <std::string, std::string> symbols = { {"PATH", "/usr/bin"},{"CWD", "/usr"} };
    std::stack<std::string> stack_;
    std::string currentToken;
    bool inToken = false;
    for (auto i =0;i<str.size();i++)
    {
        if (inToken)
        {
            auto it = symbols.find(currentToken);

            if (it==symbols.end()) currentToken += str[i];
            else 
            {
                inToken = false;
                stack_.push(symbols[currentToken]);
                currentToken.clear();
                i--;
            }

            //this code duplicates block just if it last char in string is last symbol of token
            it = symbols.find(currentToken);
            if (it != symbols.end() && (i == str.size() - 1))
            {
                inToken = false;
                stack_.push(symbols[currentToken]);
                currentToken.clear();
            }
        }
        else if (str[i] == '$')
        {
            currentToken += str[++i];
            inToken = true;
        }
        else
            stack_.push(std::string()+str[i]);
    }

    std::string result;
    while (stack_.size())
    {
        result.insert(0,stack_.top());
        stack_.pop();
    }
    return result;
}

int main()
{
    std::cout << parser("$PATH:$CWD");
}

答案 1 :(得分:0)

您可以创建一个函数,将 str1 替换为 str2 内的 str,使用 string::findstring::replace 的组合

首先找到str1在str中的位置

size_t pos = str.find(str1);

然后,您可以使用replace将str中从pospos + str1.length()的字符替换为str2

str.replace(pos, str1.length(), str2);

现在,当您拥有该函数时,您可以将其与一些 if 条件一起使用来替换字符串中所需的任何标记