忽略正则表达式中的第一个匹配项
Ignoring the first match in regex
我正在做一个来自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
标志,可以传递给format
,除非相反),才能忽略第一个匹配?但我很难找到一个。
注释掉的解决方案似乎要好一点,只是它需要通过输入进行第二次迭代。
您可以使用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
如何将正则表达式更改为类似(?<=P, *)(P)
的正则表达式(其中P
是匹配电话号码的正则表达式的缩写)。换句话说,你只对前一个电话号码后面的电话号码感兴趣。
这个建议的唯一问题是C++似乎不支持正面的向后看。
(注意:您不希望所有捕获都在第一个电话号码中。)
相关文章:
- 带有多个字符分隔符的正则表达式
- C++:正则表达式匹配代码,打印多个匹配项?
- 查找中间两个数字的正则表达式的匹配项
- C++多个正则表达式条件语法
- 使用 boost::regex (c++) 比较两个正则表达式
- 正则表达式 获取两个换行符之间的文本
- 通过正则表达式拆分字符串会切断结果的第一个字母
- 正则表达式,捕获 4 个被 括起来的数字.或行开始/结束
- 使用正则表达式在字符串中找到多个实例
- 用于匹配多个组的正则表达式
- 在Qt Creator中使用正则表达式在多个文件中查找和替换
- C++正则表达式替换第一个匹配项
- 使用正则表达式查找多个字符串的第一个实例
- 使用正则表达式查找第一个匹配C++索引
- c++将多个正则表达式提取到一个数组中
- 忽略正则表达式中的第一个匹配项
- 创建单个正则表达式而不是多个正则表达式
- 将两个正则表达式结果连接到一个输出字段中,一次只能使用一个
- 如何在C++正则表达式中的第一个匹配处停止
- 组合两个正则表达式c++0x