C++实现从指定字符串提取等号后的数字并生成新字符串
解决方案:提取等号后数字并去除负号
我懂你要的是精准提取并处理这些数值——之前用stringstream碰壁太正常了,大概率是没处理好字段里的空格或者分割逻辑。这里给你三个靠谱的C++实现方案,随便挑一个都能解决你的需求:
方法1:正则表达式(最简洁)
用C++11及以上支持的<regex>库,直接匹配等号后的正负数字,提取后去除负号即可,代码非常简洁:
#include <iostream> #include <string> #include <regex> #include <vector> int main() { std::string input = "Sep=1, V_Batt=7.40, I_Batt=-559.63, V_SA=7.20, I_SA=-0.55, I_MB=500.25, V_5v=4.95, I_5v=446.20, V_3v=3.28, I_3v=3.45, S=0, T_Batt=25.24, T_SA1=22.95, T_SA2=-4.86"; std::regex pattern(R"(=(-?\d+\.?\d*))"); // 匹配等号后的整数/小数(支持负号) std::sregex_iterator it(input.begin(), input.end(), pattern); std::sregex_iterator end; std::vector<std::string> processedNums; for (; it != end; ++it) { std::string num = (*it)[1].str(); // 移除负号(如果存在) if (!num.empty() && num.front() == '-') { num = num.substr(1); } processedNums.push_back(num); } // 拼接成目标格式字符串 std::string result; for (size_t i = 0; i < processedNums.size(); ++i) { if (i != 0) result += ","; result += processedNums[i]; } std::cout << result << std::endl; return 0; }
逻辑说明:
- 正则表达式
=(-?\d+\.?\d*)精准定位每个等号后的数字部分,捕获组1会拿到带符号的数字 - 遍历所有匹配结果,去掉负号后收集起来
- 最后用逗号拼接成你需要的格式
方法2:手动遍历解析(无需额外库)
如果你的环境不支持正则,或者更倾向于底层逻辑控制,可以手动遍历字符串提取:
#include <iostream> #include <string> #include <vector> #include <cctype> int main() { std::string input = "Sep=1, V_Batt=7.40, I_Batt=-559.63, V_SA=7.20, I_SA=-0.55, I_MB=500.25, V_5v=4.95, I_5v=446.20, V_3v=3.28, I_3v=3.45, S=0, T_Batt=25.24, T_SA1=22.95, T_SA2=-4.86"; std::vector<std::string> processedNums; size_t currentPos = 0; while ((currentPos = input.find('=', currentPos)) != std::string::npos) { currentPos++; // 跳过等号,定位到数字起始位置 size_t numEndPos = currentPos; // 向后遍历,直到遇到非数字/非小数点/非负号的字符(即逗号或字符串结尾) while (numEndPos < input.size() && (isdigit(input[numEndPos]) || input[numEndPos] == '.' || input[numEndPos] == '-')) { numEndPos++; } // 提取数字字符串并处理负号 std::string num = input.substr(currentPos, numEndPos - currentPos); if (!num.empty() && num.front() == '-') { num = num.substr(1); } processedNums.push_back(num); currentPos = numEndPos; // 从当前数字的下一位继续查找 } // 拼接结果 std::string result; for (size_t i = 0; i < processedNums.size(); ++i) { if (i != 0) result += ","; result += processedNums[i]; } std::cout << result << std::endl; return 0; }
逻辑说明:
- 循环查找每个等号的位置,定位数字的起始点
- 向后遍历确定数字的结束位置(遇到逗号就停)
- 提取数字后去除负号,最后拼接成目标字符串
方法3:改进版stringstream(贴合你之前的尝试)
如果你坚持想用stringstream,只需调整分割逻辑,处理好字段前的空格即可:
#include <iostream> #include <string> #include <sstream> #include <vector> int main() { std::string input = "Sep=1, V_Batt=7.40, I_Batt=-559.63, V_SA=7.20, I_SA=-0.55, I_MB=500.25, V_5v=4.95, I_5v=446.20, V_3v=3.28, I_3v=3.45, S=0, T_Batt=25.24, T_SA1=22.95, T_SA2=-4.86"; std::stringstream ss(input); std::string token; std::vector<std::string> processedNums; // 按逗号分割每个键值对 while (std::getline(ss, token, ',')) { // 移除键值对前面的空格(比如" V_Batt=..."里的前置空格) size_t startPos = token.find_first_not_of(' '); if (startPos != std::string::npos) { token = token.substr(startPos); } // 找到等号位置,提取后面的数字 size_t eqPos = token.find('='); if (eqPos != std::string::npos) { std::string num = token.substr(eqPos + 1); if (!num.empty() && num.front() == '-') { num = num.substr(1); } processedNums.push_back(num); } } // 拼接结果 std::string result; for (size_t i = 0; i < processedNums.size(); ++i) { if (i != 0) result += ","; result += processedNums[i]; } std::cout << result << std::endl; return 0; }
逻辑说明:
- 用
getline按逗号分割每个键值对 - 处理键值对前面的空格(这大概率是你之前用stringstream失败的原因)
- 找到等号后提取数字,去除负号后收集,最后拼接
三个方法运行后都会输出你需要的结果:1,7.40,559.63,7.20,0.55,500.25,4.95,446.20,3.28,3.45,0,25.24,22.95,4.86
内容的提问来源于stack exchange,提问作者Hoa.N
相关产品推荐
相关产品推荐

