Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
382 views
in Technique[技术] by (71.8m points)

regex - C++ primer 5 th ed. matching flag type

I have this exercise from C++ primer 5th ed.

Exercise 17.26: Rewrite your phone program so that it writes only the second and subsequent phone numbers for people with more than one phone number.

my solution for the previous exercise: A program for finding the first match and format it using the formatting string fmt and output only the first number:

int main(){

    std::string pattern = "(\()?(\d{3})(\))?([-. ])?(\d{3})([-. ])?(\d{4})";
    std::regex reg(pattern);
    std::string fmt = "$2.$5.$7 ";

    for(std::string line; std::getline(std::cin, line); )
        std::cout << std::regex_replace(line, reg, fmt, format_first_only | format_no_copy) << '
';

}

Input:

 morgan (201) 555-2368 862-555-0123
 drew (973)555.0130
 lee (609) 555-0132 2015550175 800.555-0000

Output:

201.555.2368
973.555.0130
609.555.0132
  • AS you can see it formats the first match only and outputs it. So How can I format and output all the matches but the first? I find it a bit difficult to achieve since there's no Matching Flag Type as format_second...?
question from:https://stackoverflow.com/questions/65946053/c-primer-5-th-ed-matching-flag-type

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It is a bit tricky: you need to get rid off the first match then apply the matching flag: std::regex_constants::format_no_copyinto std::regex_replace:

  • std::sregex_iterator is your choice because it can be initialized to denote the first match then we use its member: suffix().str() passing it to std::regex_replace:

      int main(){
    
          std::string pattern = "(\()?(\d{3})(\))?([-. ])?(\d{3})([-. ])?(\d{4})";
          std::regex reg(pattern);
          std::string fmt = "$2.$5.$7 ";
    
          for(std::string line; std::getline(std::cin, line); ){
              // it points to the first match (phone number)
              std::sregex_iterator it(line.cbegin(), line.cend(), reg);
              // we use suffix as the input sequence skipping the first match
              std::cout << std::regex_replace(it->suffix().str(), reg, fmt, format_no_copy) << '
    ';
          }
      }
    

Input:

 morgan (201) 555-2368 862-555-0123
 drew (973)555.0130
 lee (609) 555-0132 2015550175 800.555-0000

Output:

862.555.0123

201.555.0175 800.555.0000

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...