我正在开发一个简单的终端 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;
}
答案 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::find 和 string::replace 的组合
首先找到str1在str中的位置
size_t pos = str.find(str1);
然后,您可以使用replace将str中从pos
到pos + str1.length()
的字符替换为str2
str.replace(pos, str1.length(), str2);
现在,当您拥有该函数时,您可以将其与一些 if
条件一起使用来替换字符串中所需的任何标记