該實(shí)例通過(guò)一個(gè)函數(shù)is_email_valid 來(lái)檢查一個(gè)email地址是否是一個(gè)正確的格式。如果格式正確則返回true。
#include <regex>
#include <iostream>
#include <string>
bool is_email_valid(const std::string& email)
{
const std::regex pattern("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");
return std::regex_match(email, pattern);
}
int main()
{
std::string email1 = "marius.bancila@domain.com";
std::string email2 = "mariusbancila@domain.com";
std::string email3 = "marius_b@domain.co.uk";
std::string email4 = "marius@domain";
std::cout << email1 << " : " << (is_email_valid(email1) ?
"valid" : "invalid") << std::endl;
std::cout << email2 << " : " << (is_email_valid(email2) ?
"valid" : "invalid") << std::endl;
std::cout << email3 << " : " << (is_email_valid(email3) ?
"valid" : "invalid") << std::endl;
std::cout << email4 << " : " << (is_email_valid(email4) ?
"valid" : "invalid") << std::endl;
return 0;
}
運(yùn)行結(jié)果
這里對(duì)is_email_valid()函數(shù)中的正則表達(dá)式做一個(gè)簡(jiǎn)短的說(shuō)明,如果對(duì)于正則表示不是很清楚的同學(xué)就能很容易理解了。 下面一個(gè)例子通過(guò)正則表達(dá)式識(shí)別和打印IP地址的各個(gè)部分: #include <regex> #include <iostream> #include <string> void show_ip_parts(const std::string& ip) { // regular expression with 4 capture groups defined with // parenthesis (...) const std::regex pattern("(\\d{1,3}):(\\d{1,3}):(\\d{1,3}):(\\d{1,3})"); // object that will contain the sequence of sub-matches std:: match_results<std::string::const_iterator> result; // match the IP address with the regular expression bool valid = std:: regex_match(ip, result, pattern); std::cout << ip << " \t: " << (valid ? "valid" : "invalid") << std::endl; // if the IP address matched the regex, then print the parts if(valid) { std::cout << "b1: " << result[1] << std::endl; std::cout << "b2: " << result[2] << std::endl; std::cout << "b3: " << result[3] << std::endl; std::cout << "b4: " << result[4] << std::endl; } } int main() { show_ip_parts("1:22:33:444"); show_ip_parts("1:22:33:4444"); show_ip_parts("100:200"); return 0; } 運(yùn)行結(jié)果:
const std::regex pattern("(
是對(duì)正則表達(dá)式的模式串做一個(gè)說(shuō)明:首先還是通過(guò)‘()’將這個(gè)串分成幾個(gè)子表達(dá)式,其中\(zhòng)d表示匹配一個(gè)數(shù)字,{,}表示數(shù)字的個(gè)數(shù),例如{1,3}可以理解為匹配一個(gè)小于1000的數(shù)字(1-3位數(shù)都符合匹配要求)。
程序中還使用了match_results類(lèi),用來(lái)保存匹配的每一個(gè)子序列。調(diào)用regex_match(ip,result,pattern),表示將ip中與模式串pattern匹配的結(jié)果放在result中。
result最后可以通過(guò)下標(biāo)來(lái)訪問(wèn)各個(gè)匹配的子表達(dá)式。
下面來(lái)介紹和regex_match()很像的regex_search()的使用實(shí)例,regex_match()要求正則表達(dá)式必須與模式串完全匹配,regex_search()只要求存在匹配項(xiàng)就可以。
#include <regex>
#include <iostream>
#include <string>
int main()
{
const std::tr1::regex pattern("(\\w+day)");
// the source text
std::string weekend = "Saturday and Sunday";
std::smatch result;
bool match = std::regex_search(weekend, result, pattern);
if(match)
{
for(size_t i = 1; i < result.size(); ++i)
{
std::cout << result[i] << std::endl;
}
}
std::cout<<std::endl;
return 0;
}
運(yùn)行結(jié)果:
上面這個(gè)例子只能返回第一個(gè)匹配的項(xiàng),如果要返回所有匹配的子序列,可以使用下面的方式:
#include <regex>
#include <iostream>
#include <string>
int main()
{
// regular expression
const std::regex pattern("\\w+day");
// the source text
std::string weekend = "Saturday and Sunday, but some Fridays also.";
const std::sregex_token_iterator end; //需要注意一下這里
for (std::sregex_token_iterator i(weekend.begin(),weekend.end(), pattern); i != end ; ++i)
{
std::cout << *i << std::endl;
}
std::cout<<std::endl;
return 0;
}
運(yùn)行結(jié)果:
下面的例子將元音字母打頭的單詞前面的a替換為an:
#include <regex>
#include <iostream>
#include <string>
int main()
{
// text to transform
std::string text = "This is a element and this a unique ID.";
// regular expression with two capture groups
const std::regex pattern("(\\ba (a|e|i|u|o))+");
// the pattern for the transformation, using the second
// capture group
std::string replace = "an $2";
std::string newtext = std::regex_replace(text, pattern, replace);
std::cout << newtext << std::endl;
std::cout << std::endl;
return 0;
}
運(yùn)行結(jié)果:
還是來(lái)說(shuō)明一下,這里主要使用了regex_replace(text, pattern, replace),意思是將text的內(nèi)容按照pattern進(jìn)行匹配,匹配成功的使用replace串進(jìn)行替換,并將替換后的結(jié)果作為函數(shù)值返回。需要注意的是std::string replace = "an $2"; 這里‘$2’表示模式串的第二個(gè)子表達(dá)式,
也就是以a,e,i,o,u開(kāi)頭的單詞。
下面一個(gè)例子將進(jìn)行年月日格式的轉(zhuǎn)換,將DD-MM-YYYY –> YYYY-MM-DD,其中‘.’或者‘/’都能正確識(shí)別。
#include <regex>
#include <iostream>
#include <string>
std::string format_date(const std::string& date)
{
// regular expression
const std:: regex pattern("(\\d{1,2})(\\.|-|/)(\\d{1,2})(\\.|-|/)(\\d{4})");
// transformation pattern, reverses the position of all capture groups
std::string replacer = "$5$4$3$2$1";
// apply the tranformation
return std:: regex_replace(date, pattern, replacer);
}
int main()
{
std::string date1 = "1/2/2008";
std::string date2 = "12.08.2008";
std::cout << date1 << " -> " << format_date(date1) << std::endl;
std::cout << date2 << " -> " << format_date(date2) << std::endl;
std::cout << std::endl;
return 0;
}
運(yùn)行結(jié)果:
說(shuō)明,這個(gè)例子也很有實(shí)用價(jià)值,這里用到的正則表達(dá)式的匹配模式前面都已經(jīng)進(jìn)行過(guò)說(shuō)明就不在分析。
相信通過(guò)以上例子,對(duì)正則表達(dá)式的運(yùn)用已經(jīng)有了一個(gè)不錯(cuò)的了解,下面再來(lái)添加一個(gè)實(shí)例,加深一下理解。
下面一個(gè)例子用來(lái)查找給定文本中new的個(gè)數(shù)和delete的個(gè)數(shù)是否相等:
#include <iostream>
#include <string>
#include <regex>
int main() {
// "new" and "delete" 出現(xiàn)的次數(shù)是否一樣?
std::regex reg("(new)|(delete)");
std::smatch m;
std::string s=
"Calls to new must be followed by delete. \
Calling simply new results in a leak!";
int new_counter=0;
int delete_counter=0;
std::string::const_iterator it=s.begin();
std::string::const_iterator end=s.end();
while (std::regex_search(it,end,m,reg))
{
// 是 new 還是 delete?
m[1].matched ? ++new_counter : ++delete_counter;
it=m[0].second;
}
if (new_counter!=delete_counter)
std::cout << "Leak detected!\n";
else
std::cout << "Seems ok...\n";
std::cout << std::endl;
}
運(yùn)行結(jié)果:
運(yùn)行結(jié)果表明,new和delete的數(shù)量不相等,也就是發(fā)生了“內(nèi)存泄露”。
為了幫助理解,上面對(duì)于match_results類(lèi)型的下標(biāo)操作的意義,請(qǐng)看ISOIEC14882 C++11的說(shuō)明:
#include <iostream>
#include <string>
#include <regex>
using namespace std;
class regex_callback {
int sum_;
public:
regex_callback() : sum_(0) {}
template <typename T> void operator()(const T& what) {
sum_+=atoi(what[1].str().c_str());
}
int sum() const {
return sum_;
}
};
int main() {
regex reg("(\\d+),?");
string s="1,1,2,3,5,8,13,21";
sregex_iterator it(s.begin(),s.end(),reg);
sregex_iterator end;
regex_callback c;
int sum=for_each(it,end,c).sum();//for_each返回的是這個(gè)函數(shù)對(duì)象,因此可以調(diào)用sum
cout<<sum<<endl;
cout<<endl;
}
運(yùn)行結(jié)果:
#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main()
{
regex reg("/");
vector<std::string> vec;
string s="Split/Vulue/Teather/Neusoft/Write/By/Lanwei";
sregex_token_iterator it(s.begin(),s.end(),reg,-1);//// -1逆向匹配,就是匹配除了'/'之外的
sregex_token_iterator end ;
while(it!=end)
vec.push_back(*it++);
copy(vec.begin(),vec.end(),ostream_iterator<std::string>( cout,"\n"));
}
運(yùn)行結(jié)果:
聯(lián)系客服