C primer 5-е изд. соответствующий тип флага

#c #regex

#c #регулярное выражение

Вопрос:

У меня есть это упражнение из C primer 5-е изд.

Упражнение 17.26: Перепишите свою телефонную программу так, чтобы она записывала только второй и последующие телефонные номера для людей с более чем одним телефонным номером.

мое решение для предыдущего упражнения: программа для поиска первого совпадения и форматирования его с использованием форматирующей строки fmt и вывода только первого числа:

 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) << 'n';

}
 

Ввод:

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

Вывод:

 201.555.2368
973.555.0130
609.555.0132
 
  • КАК вы можете видеть, он форматирует только первое совпадение и выводит его. Итак, как я могу отформатировать и вывести все совпадения, кроме первого? Я нахожу это немного трудным для достижения, поскольку нет соответствующего типа флага как format_second …?

Комментарии:

1. использовать regex_search

2. Зачем голосовать против?

Ответ №1:

Это немного сложно: вам нужно избавиться от первого совпадения, а затем применить соответствующий флаг: std::regex_constants::format_no_copy в std::regex_replace :

  • std::sregex_iterator это ваш выбор, потому что он может быть инициализирован для обозначения первого совпадения, затем мы используем его член: suffix().str() передаем его в 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) << 'n';
          }
      }
     

Ввод:

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

Вывод:

 862.555.0123

201.555.0175 800.555.0000