首页 > 解决方案 > 如何从 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++splitdynamic-datadata-extraction

解决方案


我以下面的代码为例,可以做什么。

我不明白完成你的任务的确切步骤,但我知道你需要两件事 - 首先使用正则表达式或其他东西在输入字符串中查找和提取某些子字符串的匹配项,然后通过放入一些子字符串来组成新字符串第一阶段。

在下面的代码中,我实现了两个阶段 - 首先使用正则表达式提取子字符串,然后组成新字符串。

我使用了标准 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.].

推荐阅读