C++ 通过正则表达式解析多数据文本

问题描述 投票:0回答:1

待解析的文本:

001  B001C001_230130_RQ7V V     C        04:23:30:18 04:24:14:01 01:00:00:00 01:00:43:08  
*ASC_SOP (1.000000 1.000000 1.000000)(0.000000 0.000000 0.000000)(1.000000 1.000000 1.000000)
*ASC_SAT 1.000000

我正在尝试将 *ASC_SOP 三元组解析为 3x float[3] 数组。

源文件逐行加载并传递给

parse()
函数。当前函数如下所示:

inline void parse(std::string &line) {

    //regex to match edl id's camera reel and slope values
    std::regex edlID("^([0-9]{3})");
    std::regex camReel("([A-Za-z]([0-9]{3}))\\S+");
    std::regex SOP("(?:[0-9][.][0-9]{6})");

    std::smatch mID, reelID, sopMatch; //regex matchers

    //check if there is an edlID. As per CM3600 spec this is always the first column
    if(std::regex_search(line, mID, edlID)) {
        std::regex_search(line, reelID, camReel); //next we check for a clip/reel name combo
        std::cout << "EDL ID: " << mID[0] << " Clip: " << reelID[0] << std::endl;
    }
}

将 *ASC_SOP 值和 ASC_SAT 值解析为相应浮点数的最佳方法是什么?正则表达式是最好的解决方案吗?还是基于令牌的 stringstream 更好?一个想法是去掉所有括号的行,然后用

' '
分隔符再次迭代。有没有人有有效的方法来处理这个?

c++ regex stringstream
1个回答
0
投票

假设您在这里关心的行始终遵循相同的基本模式:

*ASC_SOP
后跟三组括号,每组包含三个浮点数,我可能会使用
stringstream
。对于这样的情况,我通常从一个小的固定模式匹配器开始1

std::istream &operator>>(std::istream &is, char const *pat) {
    while (is.peek() == *pat) {
        ++pat;
        is.ignore(1);
    }
    if (*pat)
        is.setstate(std::ios::failbit);
    return is;
}

有了这个,我们可以做这样的匹配:

    float a[3], b[3], c[3];

    if (input >> "*ASC_SOP (" >> a[0] >> a[1] >> a[2] >> ")(" 
                              >> b[0] >> b[1] >> b[2] >> ")(" 
                              >> c[0] >> c[1] >> c[2] >> ")") 
    {
        std::cout << "parsed ASC_SOP\n";
    } else {
        std::cerr << "Attempt at parsing ASC_SOP failed\n";
    }

尽管模式匹配器本身并不完全直观,至少对我而言,它似乎使其余代码非常清晰易懂(一旦您理解了它的目的,模式匹配器就不是特别困难要么)。


  1. 根据情况,将其做得更详细一些是有意义的,例如如果设置了流
    skipws
    标志,让它匹配模式中的任何空白与输入流中任意数量的空白,比如出现在
    scanf
    和公司的形式字符串中。如果(例如)在下一个左括号和下一个左括号之间可能有或没有空格(或可能没有制表符),这可能很有用。但是一旦你有了基本的想法,如果需要的话,添加这样的东西就很容易了。
© www.soinside.com 2019 - 2024. All rights reserved.