简体   繁体   中英

Getting full name and values from string with regex and c++

I have a project where I am reading data from a text file in c++ which contains a person's name and up to 4 numerical numbers like this. (each line has an entry)

Dave Light 89 71 91 89
Hua Tran Du 81 79 80 

I am wondering if regex would be an efficient way of splitting the name and numerical values or if I should find an alternative method.

I would also like to be able to pick up any errors in the text file when reading each entry such as a letter instead of a number as if an entry like this was found.

Andrew Van Den J 88 95 85

This non -regex solution:

std::string str = "Dave Light 89 71 91 89";
std::size_t firstDig = str.find_first_of("0123456789");
std::string str1 = str.substr (0,firstDig);
std::string str2 = str.substr (firstDig);

would give you the letter part in str1 and the number part in str2.

Check this code at ideone.com .

It sounds like it's something like this you want...(?) I'm not quite sure what kind of errors you mean to pick. As paxdiablo pointed out, a name could be quite complex, so getting the letter part probably would be the safest.

You should better use a separator instead of space. The separator could be : , | , ^ or anything that cannot be part of your data. With this approach, your data should be stored as:

Dave Light:89:71:91:89
Hua Tran Du:81:79:80 

And then you can use find , find_first_of , strchr or strstr or any other searching (and re-searching) to find relevant data.

Try this code.

#include <iostream>
#include <regex>
#include <string>
#include <vector>

int main(){
    std::vector<std::string> data {"Dave Light 89 71 91 ","Hua Tran Du 81 79 80","zyx 1 2 3 4","zyx 1 2"};
    std::regex pat {R"((^[A-Za-z\s]*)(\d+)\s*(\d+)\s*(\d+)(\s*)$)"};
    for(auto& line : data) {
        std::cout<<line<<std::endl;
        std::smatch matches; // matched strings go here
        if (regex_search(line, matches, pat)) {
            //std::cout<<"size:"<<matches.size()<<std::endl;
            if (matches.size()==6)
                std::cout<<"Name:"<<matches[1].str()<<"\t"<<"data1:"<<matches[2].str()<<"\tdata2:"<<matches[3].str()<<"\tdata3:"<<matches[4].str()<<std::endl;
        }
    }
}

With regex number of lines code reduced greatly. Main trick in regex is using right pattern.

Hope this will help you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM