【问题标题】:C++ get string between two delimiters and replace itC ++获取两个分隔符之间的字符串并替换它
【发布时间】:2018-07-31 17:05:28
【问题描述】:

我想用取决于分隔符之间的子字符串的东西替换字符串中的子字符串。小例子:

我得到了字符串

The result is __--__3__--__.

还有一个函数

int square(int x): { return x*x };

现在我想只输出带有结果的字符串,不带分隔符,所以:

The result is 9.

我已经尝试了几种算法,但都没有奏效。 最好的尊重

我最好的尝试:

    const std::string emptyString = "";
std::string ExtractString(std::string source, std::string start, std::string end)
{
    std::size_t startIndex = source.find(start);

    // If the starting delimiter is not found on the string
    // stop the process, you're done!
    //
    if (startIndex == std::string::npos)
    {
        return emptyString;
    }

    // Adding the length of the delimiter to our starting index
    // this will move us to the beginning of our sub-string.
    //
    startIndex += start.length();

    // Looking for the end delimiter
    //
    std::string::size_type endIndex = source.find(end, startIndex);

    // Returning the substring between the start index and
    // the end index. If the endindex is invalid then the
    // returned value is empty string.
    return source.substr(startIndex, endIndex - startIndex);
}

int square(int x): { return x*x };

int main() {
    std::string str = "The result is __--__3__--__.";
    std::string foundNum = ExtractString(str, "__--__", "__--__");
    int foundNumInt = atoi(foundNum.c_str());
    int result = square(foundNumInt);
    std::string toReplace = "__--__";
    toReplace.append(foundNumInt);
    toReplace.append("__--__");
    str.replace(str.begin(), str.end(), toReplace, result);
}

问题是:如何获取给定的第一个字符串(The result is __--__<number>__--__.>,从中获取数字,对该数字执行函数,然后以类似于 The result is <number squared> 的字符串结尾。

【问题讨论】:

  • 使用std::regex 无论如何你没有表现出任何努力,这似乎是一个家庭作业。
  • The result is __--__3__--__. 的用途是什么,比如空白点是什么意思?我不完全是您想要替换的内容以及您想要做的事情......
  • @CU_dev 假设我从服务器获得了带有此消息的输入。我想用函数调用 square(3) 的结果替换子字符串“__ -3--__”(对不起,粗体字符,这是stackoverflow的格式)
  • 所以你想找到 3,然后用答案替换 is 之后的所有内容?
  • 如果代码实际上是 C++ 而不是其他东西,那就太好了。 请显示您尝试过的代码

标签: c++ string delimiter


【解决方案1】:

这是一种取第一个字符串,找到数字的方法。然后我只是将数字平方,但您可以将其插入您想要的函数中。

std::string s = "The result is __--__3__--__.";
std::regex r( "[0-9]+");
std::smatch m;

//
std::sregex_iterator iter(s.begin(), s.end(), r);
std::sregex_iterator end;
std::string value;
//
int index = 0;
while (iter != end)
{
    for (unsigned i = 0; i < iter->size(); ++i)
    {
        value = (*iter)[i];
    }
    ++iter;
    index++;
}

int num = stoi(value);

int answer = num*num;

s = s.substr(0, s.find('_'));
s = s + " " + std::to_string(answer);

std::cout << s << std::endl;

【讨论】:

    【解决方案2】:

    你试过std::string::find吗?

    const std::string example_data = "The result is __--__3__--__.";
    static const char text_to_find[] = "__--__";
    const std::string::size_type start_position = example_data.find(text_to_find);
    if (start_position != std::string::npos)
    {
      const std::string::size_type replacement_start_position = start_position + sizeof(text_to_find) - 1;
      if (replacement_start_position < example_data.length())
      {
        // Perform replacement
      }
    }
    

    “sizeof(text_to_find) - 1”返回文本的长度,不计算终止nul字符。

    要跳过数字,您可以执行以下操作:

    const std::string after_number_position = example_data.find(replacement_start_position, "_");
    

    replacement_start_positionafter_number_position 之间的子字符串将包含您的号码。您可以使用多种函数将子字符串转换为数字。

    另请参阅std::ostringstream,了解如何将数字转换为文本。

    编辑 1:
    更正了 replacement_start_position 的声明。

    【讨论】:

    • 您可能应该使用sizeof 添加警告,因为它通常会被滥用。
    • 是的,我也尝试过这样的事情。问题是,3 甚至可以是 10 或 100。虽然 --_3--_ 之前的文本可以更改。在 Python 中,这将非常简单..
    • 如果您注意到,我发布的代码会搜索数字后面的关键字符。这消除了对文本运行数字解析器的需要。也可以将子串放入std::istringstream中读入数字。
    • 编译器错误。将所有std::string::size_type 转换为size_t
    • @ThomasMatthews 这只是一个错字。您在if 中错过了::size_type
    【解决方案3】:

    你必须需要这些函数(对于 c++17,要快得多):

    auto replace_all
    (std::string str, std::string_view from, std::string_view to) noexcept -> decltype(str) {
        unsigned start_pos{ 0 };
    
        while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
            str.replace(start_pos, from.length(), to);
            start_pos += to.length();
        }
        return str;
    }
    
    auto remove_all
    (std::string str, std::string_view from) noexcept -> decltype(str) {
        return replace_all(str, from, "");
    }
    

    对于更高版本:

    std::string replace_all
    (std::string str, std::string from, std::string to) noexcept {
        unsigned start_pos{ 0 };
    
        while ((start_pos = str.find(from, start_pos)) != std::string::npos) {
            str.replace(start_pos, from.length(), to);
            start_pos += to.length();
        }
        return str;
    }
    
    std::string remove_all
    (std::string str, std::string from) noexcept {
        return replace_all(str, from, "");
    }
    

    我测试过:

    int main() {
        std::string str = "__+__hello__+__";
        std::cout << remove_all(str, "__+__");
    
        std::cin.get();
    
        return 0;
    }
    

    我的输出是:

    hello
    

    【讨论】:

      猜你喜欢
      • 2021-04-04
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-05
      • 2020-12-01
      相关资源
      最近更新 更多