如何将一行解析成碎片并忽略它的一部分? [英] How do I parse a line into pieces and ignore parts of it?

查看:130
本文介绍了如何将一行解析成碎片并忽略它的一部分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对不起。我以前不是clair。我有一个包含以下格式的数据的文件


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是每个任务的长度
其他的char是在第一个char



所以我创建了类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);
}
}


$ b

  string行; 
list< Task> * allTaches = new list< Task>();

while(getline(file,line,','))
{
//我想能够从文件中接收解析行并将其添加为
//allTaches.push_back(line)
//但是格式需要看起来像(Char,duration,<一个> PrecedentChar的列表)
//当我做
cout <线<< Lendl;
它打印
A(3)
B(4)
A
C(2)
A
E(5)
A
}

所以我不知道该怎么做。 / p>

解决方案

您可以使用正则表达式来解析所需的部分,然后将它们传递给 / code>



在使用 std :: regex



下面的代码将帮助你理解如何解析这些部分,将它们应用于测试是一个简单的步骤,但最好由你做,以确保概念是清楚的。



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



如果我们分解你有什么 - 它是:



某事,一个开放的括号我们不想要的东西,一个闭合的括号我们不想要,我们不想要,而且在简单的正则表达式中有一些



 (。*)\((。*)\),(。*)



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



第二个东西以闭合括号结束,所以我们有([^)])



一个可选的逗号,但是我们可以使用(。*),然后在可选的 * em>(可能有更好的方法)



我们还需要双重转义 \ 一次为编译器,一次为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 {
std :: cout< result [i]<< std :: endl;
}
}
else
{
std :: cout< NO MATCH< std :: endl;
}
} catch(std :: regex_error& e){

std :: cout< BAD REGEX<< std :: endl;
}

}


I am sorry. I wasn't clair previously. I have a file that include data in the following format

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

...

These data represent a graph.

I will use the critical path method to calculate how to get through this text file.

the char is the step the int is the length of each task the other char is step that come before the first char

So I have created the class Task to read the file and its constructor have the following parameters

    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);
         }
   }

In the main I added

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 
 }

So I am not sure to know what to do really.

解决方案

You can use a regular expression to parse out the pieces you need and then pass them to Task

In c++ that is done using std::regex

The code below will help you understand how to parse out the pieces, applying them to test is a simple step from there, but best done by you to make sure the concept is clear.

First we will need a regular expression that grabs each piece, this is called a capture group and all that is needed is to use parenthesis

If we break down what you have - it is:

Something, an open paren we dont want, Something, a close paren we dont want, a comma we don't want, and Something

in simple regex that would be:

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

But things are never so simple

The first Something ends with the open paren, so we want everything but that first open paren: ([^(]) the ^ means not, the square bracket [] means every character

The second Something ends with the close paren, so we have ([^)])

The third something excludes the optional comma, but we can use (.*) and then group the , in an optional * (There is likely a better way to do this)

We also need to double escape the \ once for the compiler and once for regex

We also need to allow for people entering random spaces in there so we add * in all breaks

This leads to our regex:

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

Then we search and if found it will be in the result and we can iterate it to get the pieces.

#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;
        }

}

这篇关于如何将一行解析成碎片并忽略它的一部分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆