c++ primer第5版匹配标志类型



这个练习来自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…?

这有点棘手:您需要摆脱第一个匹配,然后应用匹配标志:std::regex_constants::format_no_copystd::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

最新更新