c++ - 如何从 C++ 中的字符串中提取多组动态数字?
问题描述
我想从一个字符串中提取几组数字并将它们相应地粘贴到另一个字符串中。
假设有一个对话框,我们将 WndCaption 作为字符串 A(输入字符串)。
字符串 A:Voltage: 2.0V, Current:0.4A, Resistance: 5.0Ω, Power: 1.5W.
字符串 A 是动态输入,它取决于对话框的 WndCaption。例如,字符串 A 也可以是The apple is inside column: 12, row: 3, box: 5.
字符串 B(输入参考字符串)与字符串 A 完全相同,只是数字被分隔符替换。它用于从字符串 A 中提取数字。
字符串 B:Voltage: %fV, Current:%fA, Resistance: %fΩ, Power: %fW.
然后这是字符串 C(输出参考字符串),
字符串 C:The answers are %fV; %fA; %fΩ; %fW.
字符串 B 和字符串 C 配对在一起,它们使用 .txt 从数据库(.txt 文件)获取std::vector<>::data
。
问题是:如何提取这 4 组数字并将它们粘贴到字符串 C 中并获得最终输出为The answers are 2.0V; 0.4A; 5.0Ω; 1.5W.
?
我试图实现拆分和合并方法,但在这种情况下似乎是不可能的。任何想法?
解决方案
我以下面的代码为例,可以做什么。
我不明白完成你的任务的确切步骤,但我知道你需要两件事 - 首先使用正则表达式或其他东西在输入字符串中查找和提取某些子字符串的匹配项,然后通过放入一些子字符串来组成新字符串第一阶段。
在下面的代码中,我实现了两个阶段 - 首先使用正则表达式提取子字符串,然后组成新字符串。
我使用了标准 C++ 模块std::regex中的函数和对象。我还编写了一个特殊的辅助函数string_format(format, args...)
来对组合结果进行格式化,格式化是通过这里描述的格式化说明符来实现的。
您可以通过首先提取必要的子字符串和组合结果格式化字符串多次重复下一个代码来实现您的目标。
接下来的代码也可以在这里在线运行!或在这里!
#include <regex>
#include <string>
#include <regex>
#include <iostream>
#include <stdexcept>
#include <memory>
using namespace std;
// Possible formatting arguments are described here https://en.cppreference.com/w/cpp/io/c/fprintf
template<typename ... Args>
std::string string_format( const std::string& format, Args ... args )
{
size_t size = snprintf( nullptr, 0, format.c_str(), args ... ) + 1; // Extra space for '\0'
if( size <= 0 ){ throw std::runtime_error( "Error during formatting." ); }
std::unique_ptr<char[]> buf( new char[ size ] );
snprintf( buf.get(), size, format.c_str(), args ... );
return std::string( buf.get(), buf.get() + size - 1 ); // We don't want the '\0' inside
}
int main() {
try {
string str = "abc12345DEF xyz12ABcd";
cout << "Input string [" << str << "]." << endl;
string sre0 = "\\d+[A-Z]+";
// https://en.cppreference.com/w/cpp/header/regex
std::regex re0(sre0);
vector<string> elems;
std::sregex_token_iterator iter(str.begin(), str.end(), re0, 0);
std::sregex_token_iterator end;
while (iter != end) {
elems.push_back(*iter);
++iter;
cout << "matched [" << elems.back() << "] " << endl;
}
string fmt = "New String part0 \"%s\" and part1 \"%s\" and some number %d.";
string formatted = string_format(fmt.c_str(), elems.at(0).c_str(), elems.at(1).c_str(), 987);
cout << "Formatted [" << formatted << "]." << endl;
return 0;
} catch (exception const & ex) {
cout << "Exception: " << ex.what() << endl;
return -1;
}
}
代码输出:
Input string [abc12345DEF xyz12ABcd].
matched [12345DEF]
matched [12AB]
Formatted [New String part0 "12345DEF" and part1 "12AB" and some number 987.].
推荐阅读
- android - 即使在 layout_height 上使用 WRAP_CONTENT,RecycleView 也会显示间隙之间的额外空间
- javascript - onchange 方法未触发
- amazon-web-services - 忽略指定内容类型的 Amazon S3 直接上传
- ios - 在 iOS 上过滤裸露/露骨用户生成内容的标准方法
- validation - 无法在原始类型 int 上调用 length()
- asp.net - 当 ASP.Net Core 返回 413(请求正文太大)时,如何阻止 IIS 返回 502.3 - Bad Gateway?
- python - python:对非零填充的对象使用 strptime()
- android - 无法在 Android Studio 中使用包创建
- javascript - 角度 4 嵌套的 formArray / formGroup 将值从 DB 查询返回到表单中
- python - 是否有一种更简洁的 Pythonic 方式来忽略对未初始化属性的调用?