忽略正则表达式中的第一个匹配

时间:2015-12-12 19:13:44

标签: c++ regex c++11

我正在使用C ++ Primer进行练习

  

重写您的手机程序,使其只能写入   具有多个电话的人的第二个和后续电话号码   号。

(手机程序只使用正则表达式识别具有特定格式的电话号码)。

本章一直在讨论使用regex_replace和格式标志来改变输入的电话号码的格式。问题是要求忽略输入的第一个电话号码,只格式化/打印第二个及后续电话号码。我的输入可能类似于:

dave: 050 000 0020, (402)2031032, (999) 999-2222

它应该输出

402.203.1032 999.999.2222

这是我的解决方案:

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

using namespace std;
using namespace regex_constants;

int main(){

    string pattern = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";

    regex r(pattern);

    //string firstFormat = "";
    string secondFormat = "$2.$5.$7 ";

    for(string line; getline(cin, line);){
        unsigned counter = 0;
        for(sregex_iterator b(line.begin(), line.end(), r), e; b != e; ++b)
            if(++counter > 1) cout << (*b).format(secondFormat);
        cout << endl;

//      Below: iterates through twice, maybe not ideal
//      string noFirst = regex_replace(line, r, firstFormat, format_first_only); //removes the first phone number
//      cout << regex_replace(noFirst, r, secondFormat, format_no_copy) << endl;
    }


}

但是我对使用计数器感到不满意,以确保我没有处理第一场比赛。感觉必须有一个更自然的实用程序(比如可以传递给format_first_only的{​​{1}}标志,反之除外)可以忽略第一个匹配?但我很难找到一个。

注释掉的解决方案看起来好一点,除了它需要通过输入进行第二次迭代。

2 个答案:

答案 0 :(得分:0)

如何将正则表达式更改为(?<=\P, *)(\P)(其中\P是与电话号码匹配的正则表达式的简写)。换句话说,您只对按照之前电话号码的电话号码感兴趣。

这个建议的唯一问题是C ++似乎不支持积极的后视。

(注意:您不希望第一个电话号码中的所有捕获。)

答案 1 :(得分:0)

您可以使用\G锚点。

"(?:(?!\\A)\\G|.*?\\d{3}\\D*\\d{3}\\D*\\d{4}).*?(\\d{3})\\D*(\\d{3})\\D*(\\d{4})"

并且secondFormat = "$1.$2.$3 ";
不需要柜台的地方。

格式化:

 (?:
      (?! \A )                      # Not beginning of string
      \G                            # End of previous match
   |                              # or,
      .*?                           # Anything up to
      \d{3} \D* \d{3} \D* \d{4}     # First phone number
 )
 .*?                           # Anything up to
 ( \d{3} )                     # (1), Next phone number
 \D* 
 ( \d{3} )                     # (2)
 \D* 
 ( \d{4} )                     # (3)

输入:

dave: 050 000 0020, (402)2031032, (999) 999-2221

输出:

 **  Grp 0 -  ( pos 0 , len 32 ) 
dave: 050 000 0020, (402)2031032  
 **  Grp 1 -  ( pos 21 , len 3 ) 
402  
 **  Grp 2 -  ( pos 25 , len 3 ) 
203  
 **  Grp 3 -  ( pos 28 , len 4 ) 
1032  

-------------------------------------

 **  Grp 0 -  ( pos 32 , len 16 ) 
, (999) 999-2221  
 **  Grp 1 -  ( pos 35 , len 3 ) 
999  
 **  Grp 2 -  ( pos 40 , len 3 ) 
999  
 **  Grp 3 -  ( pos 44 , len 4 ) 
2221