#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