如何将一行解析为多个部分并忽略其中的部分

How do I parse a line into pieces and ignore parts of it?

本文关键字:个部 一行      更新时间:2023-10-16

对不起。我以前不是克莱尔。我有一个文件,包括以下格式的数据

A(3)

B(4),A

C(2),A

E(5),A

G(3),A

J(8),B,H

H(7),C,E,G

I(6),G

F(5),H

这些数据表示一个图形。

我将使用关键路径方法来计算如何通过此文本文件。

char是步骤int是每个任务的长度另一个字符是在第一个字符之前的步骤

因此,我创建了类Task来读取文件,其构造函数具有以下参数

    Tache::Tache(char step2, int duration, list<Task*> precedentTask)
    {
          this->step = step2;
          this -> duration = duration; 
          for(list<Task*>::iterator it = this-> precedentTask.begin(); it != this-> precedentTask.end(); it++)
         {
              this-> precedentTask.push_back(*it);
         }
   }

我主要添加了

string line;
list<Task> *allTaches = new list<Task>();
  while(getline(file, line, ','))
 {
       //I want to be able to receive the parse line from the file and add it like
     //allTaches.push_back(line)
     //But the format needs to look like (Char, duration, <a list of> PrecedentChar)           
     //when I do 
     cout<< line << Lendl;
    it prints 
    A(3)
    B(4)
    A
    C(2)
    A
    E(5)
    A 
 }

所以我不知道该怎么做。

您可以使用正则表达式解析出所需的片段,然后将它们传递给Task

在c++中,使用std::regex 完成

下面的代码将帮助您理解如何解析这些片段,将它们应用于测试是一个简单的步骤,但最好由您来确保概念清晰。

首先,我们需要一个正则表达式来抓取每个片段,这被称为捕获组,所需要的只是使用括号

如果我们把你的东西分解一下,那就是:

有些东西,一个我们不想要的开括号,有些东西,我们不想要一个闭括号,一个逗号,还有一些

在简单的正则表达式中为:

(.*)((.*)),(.*)

但事情从来没有这么简单

第一个Something以开括号结尾,所以我们想要除了第一个开括号之外的所有内容:([^(]) ^表示不,方括号[]表示每个字符

第二个Something以闭合paren结束,所以我们有([^)])

第三个something排除了可选的逗号,但我们可以使用(.*),然后将其分组为可选的*(可能有更好的方法)

我们还需要为编译器和regex 分别对进行一次双转义

我们还需要允许人们进入其中的随机空间,因此我们在所有中断中添加*

这导致了我们的正则表达式:

*([^(]*) *\( *([^)]*) *\) *(, *(.*))*

然后我们搜索,如果找到了,就会出现在结果中,我们可以迭代它来获得片段。

#include <iostream>
#include <string>
#include <regex>
int main()
{
        // std::string seq = "A(4),B";
        std::string seq = "A(4)";
        try {
                std::regex rgx(" *([^(]*) *\( *([^)]*) *\) *(, *(.*))*");
                std::smatch result;
                if(std::regex_search(seq, result, rgx))
                {
                        std::cout << "Size=" << result.size() << std::endl;
                        for(size_t i=0; i<result.size(); ++i)
                        {
                                std::cout << result[i] << std::endl;
                        }
                }
                else
                {
                        std::cout << "NO MATCH" << std::endl;
                }
        } catch (std::regex_error& e) {
                std::cout << "BAD REGEX" << std::endl;
        }
}

这里实际要做的是为Tache对象创建一个提取运算符。我假设你的代码看起来像这样:

typedef char Task;
struct Tache {
    char step;
    int duration;
    list<Task> precedentTask;
};

您的提取运算符将是Tache的一种方法。它的暴力实现看起来像这样:

istream& operator>>(istream& lhs, Tache& rhs) {
    string line;
    getline(lhs, line, 'n');
    stringstream ss(line);
    ss >> rhs.step;
    ss.ignore(numeric_limits<streamsize>::max(), '(');
    ss >> rhs.duration;
    ss.ignore(numeric_limits<streamsize>::max(), ')');
    const regex re("\s*,\s*([a-zA-Z])");
    string precedentTasks;
    getline(ss, precedentTasks);
    rhs.precedentTask.clear();
    transform(sregex_token_iterator(cbegin(precedentTasks), cend(precedentTasks), re, 1), sregex_token_iterator(), back_insert_iterator<list<Task>>(rhs.precedentTask), [](const string& i) {
        return i.front();
    });
    return lhs;
}

实时示例