在C++ STD::字符串中解析(替换)

在C++ STD::字符串中解析(替换),c++,C++,我有一个自定义字符串,其格式如下。例如: std::string MyString = "RndOrder%5d - RndCustomer%8s - RndHex%8x"; 我想替换/分析字符串: %5d%NUM\d将替换为随机的5位小数 %8s%NUM_将替换为随机的8个字符 %8x%NUM\u x将替换为随机的8位十六进制 有没有什么函数可以帮助我解析这些特殊标记?我不确定是否必须逐个字符地解析字符串,并检查所有可能的组合 如果格式可以是可变的,但不总是固定的3个参数:%5d、%8s和%

我有一个自定义字符串,其格式如下。例如:

std::string MyString = "RndOrder%5d - RndCustomer%8s - RndHex%8x";
我想替换/分析字符串:

%5d%NUM\d将替换为随机的5位小数

%8s%NUM_将替换为随机的8个字符

%8x%NUM\u x将替换为随机的8位十六进制


有没有什么函数可以帮助我解析这些特殊标记?我不确定是否必须逐个字符地解析字符串,并检查所有可能的组合

如果格式可以是可变的,但不总是固定的3个参数:%5d、%8s和%8x,并且您希望以这种方式灵活,那么您应该为此编写自己的实现

假设在%之后定义的计数是一个普通数字,而不仅仅是5或8,您可以尝试使用或来查找您要查找的实际助记符。例如,您的表达式可能看起来像%\d+[dsx]

然后,您应该解析它以找到计数和类型,并用用所需数据获取的随机数替换。 要进行分析,可以尝试将上述表达式更新为%\d+[dsx]并捕获组

您案例的示例解析实现可能如下所示:

std::string text = "RndOrder%5d - RndCustomer%8s - RndHex%8x";
auto reg = std::regex("%(\\d+)([sdx])");
std::smatch match;
while (std::regex_search(text, match, reg))
{
    const auto& full = match.str(); // in 1st iter contains "%5d"
    const auto& count = match.str(1); // in 1st iter contains "5"
    const auto& type = match.str(2); // in 1st iter contains "d"
    // further processing: type conversion, number generation, string replacement

    text = match.suffix().str();
}

对于搜索和组捕获的实现示例,您还可以检查另一个问题:

好,假设您实际上是在询问字符串解析,而不是随机数/数据生成。。。看看这个:

int iRandom1 = 12345;       // 5-digit decimal
int iRandom3 = 0x12345678;  // 8-digit hexadecimal
char cRandom2[9] = "RandomXY\0";  // Don't forget to NULL-terminate!
std::string sFormat = "RndOrder%5d - RndCustomer%8s - RndHex%8x";

char cResultBuffer[500];  // Make sure this buffer is big enough!

std::sprintf( cResultBuffer, sFormat.c_str(), iRandom1, cRandom2, iRandom3 );
std::string MyString = cResultBuffer;  // MyString = "RndOrder12345 - RndCustomerRandomXY - RndHex12345678";
它是std::snprintf c++14的候选者,但请注意在一次调用中请求正确的缓冲区大小,分配一个缓冲区,然后将字符串格式化到缓冲区中:

#include <iostream>
#include <cstring>
#include <string>

template<class...Args>
std::string replace(const char* format, Args const&... args)
{
    // determine number of characters in output
    auto len = std::snprintf(nullptr, 0, format, args...);

    // allocate buffer space
    auto result = std::string(std::size_t(len), ' ');

    // write string into buffer. Note the +1 is allowing for the implicit trailing
    // zero in a std::string
    std::snprintf(&result[0], len + 1, format, args...);

    return result;
};

int main() {
    auto s = replace("RndOrder%5d - RndCustomer%8s - RndHex%8x", 5, "foo", 257);
    std::cout << s << std::endl;
}

不,没有。不是C++,当然,C++中有。查一下Boost.Spirit.Or string::substr,它至少能帮你实现一部分目标。我不太明白。printf在这种情况下有什么问题?您可以使用。这个答案中的字符串解析在哪里?您是如何检测参数格式和生成值中的位数/字符数的?谢谢!但这是固定格式的。我希望接受其他sFormat字符串,例如rnd_id_u6d[dsx],而不是[d,s,x]。也可以添加+:\d+。非常感谢!这对我有帮助!我很高兴能帮上忙。那样的话,你可以接受答案
RndOrder    5 - RndCustomer     foo - RndHex     101