在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