(1)正则表达式是一种描述字符序列的方法,是一种极其强大的计算工具.在c++中,RE库是正则表达式库,它定义在头文件regex中.
regex类表示一个正则表达式,它支持很多操作,下面就通过几个例子看感受一下.
例子(1):拼写规则中,一个i除非出现在c之后,否则不可能出现ei字符串.用正则表达式来匹配不合规则的单词.
string pattern("[^c]ei");
pattern = "[[:alpha:]]*" + pattern+"[[:alpha:]]*";
regex r(pattern,regex::icase);
string test_str = "receipt fresind theif receive";
smatch ret;
if(regex_search(test_str,results,r))
cout<<result.str()<<endl;
===========================================
匹配与Regex迭代器类型.在上一个例子中,我们只能获得第一个匹配的单词。但是我们可以用sregx_iterator来获得所有匹配的单词.
string pattern("[^c]ei");
pattern = "[[:alpha:]]*" + pattern+"[[:alpha:]]*";
regex r(pattern,regex::icase);
string test_str = "receipt fresind theif receive";
smatch ret;
while (cin>>test_str)
{
for (sregex_iterator it(test_str.begin(), test_str.end(), r), end; it != end; ++it)
cout << it->str() << "\t";
cout << endl;
}
子表达式的运用
例子2:检测电话号码的格式是否正确.电话号码由区号和一个7位的本地号码组成.区号通常放在括号里,也可以不放.剩下的7个数字可以用一个短横线,一个点或者是一个空格分隔,但是也可以完全不用分隔符好。我们可以分成两步来实现这个问题.首先,我们将用一个正则表达式找到可能是电话号码的序列,然后调用一个函数来验证它.在这个验证的函数中,就需要用到子表达式是否匹配来进行判断.
bool valid(const smatch& m)
{
if (m[1].matched)//左括号匹配
return m[3].matched && (m[4].matched == 0 || m[4].str() == " ");
else//左括号不匹配
return !m[3].matched && (m[4].str() == m[6].str());
}
int main()
{
string phone = "(\\()?(\\d{3})(\\))?([._ ])?(\\d{3})([._ ])?(\\d{3})";
regex r(phone);
string s;
while (getline(cin, s))
{
for (sregex_iterator it(s.begin(), s.end(), r), end; it != end; ++it)
{
if (valid(*it))
cout << "phone: " << it->str() << endl;
else
cout << "erro_type\n";
}
}
return 0;
}
==========================================
例子4:regex_replace可以进行格式替换,具体参见书上.将电话号码的格式替换为xxx.xxx.xxxx
fstream in("Text.txt");
string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
smatch ret;
regex r(phone);
string s,fmt("$2.$5.$7 ");
while (getline(in, s))
{
cout << regex_replace(s, r, fmt,format_no_copy) << endl;
}
return 0;
======================================================================================
例子5:只输出第一个人的电话.
while (getline(in, s))
{
istringstream record(regex_replace(s, r, fmt));//将record绑定到输出的结果
record >> name;
record >> phone_number;//记录第一个电话
cout << name << "\t" << phone_number << endl;
}
例子6:对于电话多余一个的人输出第二个与后面的电话.
fstream in("Text.txt");
string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
regex r(phone);
string s,fmt("$2.$5.$7 ");
string name,phone_number;
while (getline(in, s))
{
istringstream record(regex_replace(s, r, fmt));//将record绑定到输出的结果
record >> name;
cout << name << " :";//输出人名字
vector<string> phone_num;
size_t count;
for (count = 0; record >> phone_number; ++count)
phone_num.push_back(phone_number);
if (count == 1)
cout << phone_num[0];
else
for (auto it = phone_num.begin() + 1; it != phone_num.end(); ++it)
cout << *it << " ";
cout << endl;
}
return 0;
}