17.3节练习

练习17.14 编写几个正则表达式,分别触发不同错误。运行你的程序,观察编译器对每个错误的输出。

#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main()

{
	try {
		regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase);
	}
	catch(regex_error e){
		cout << e.what() << "\ncode: " << e.code() << endl;
	}

	try
	{
		regex t("[[:alnum]]+\\.(cpp|cxx|cc)$");
	}
	catch (regex_error e)
	{	
		cout << e.what() << "\ncode: " << e.code() << endl;
	}
	
}

练习17.15 编写程序,使用模式查找违反“i在e之前,除非在c之后”规则的单词。你的程序应该提示用户输入一个单词,然后指出此单词是否符合要求。用一些违反和未违反的单词测试你程序。

#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main()
{
	string s;
	string parttern("[^c]ei");
	parttern = "[[:alpha:]]*" + parttern + "[[:alpha:]]*";
	regex r(parttern);
	smatch result;
	while (cin >> s) {
		if (regex_search(s, result, r)) {
			cout << "wanted: " << result.str() << endl;
		}
		else {
			cout << "not wanted: " << s << endl;
		}
	}
}

练习17.16 如果前一题程序中的regex对象用“[^c]ei”进行初始化,将会发生什么?用此模式测试你的程序,检查你的答案是否正确。

输出想要的字符串为  ?ei。其中?代表非c的字符。


练习17.17 更新你的程序,令它查找输入序列中所有违反"ei"语法规则的单词。

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

using namespace std;
int main()
{
	string parttern("[^c]ei");
	regex r("[[:alpha:]]*"+parttern+"[[:alpha:]]*", regex::icase);
	
	string svec = "freind receipt receive theif";
	for (sregex_iterator it(svec.begin(), svec.end(), r), end_it; it != end_it; ++it) {
		cout << it->str() << endl;
	}
}

练习17.18 修改你的程序,忽略包含"ei"但非拼写错误的单词,如"albeit"和"neighbor"。

【转载,侵删】

    #include <iostream>  
    #include <string>  
    #include <regex>  
    #include <fstream>  
    #include <vector>  
    int main(int argc, char **argv)  
    {  
        using namespace std;  
        ifstream file(argv[1]);  
        if (!file)  
        {  
            cerr << "open file error!";  
            exit(1);  
        }  
        string p("[^c]ei");  
        p = "[[:alpha:]]*" + p + "[[:alpha:]]*";  
        regex reg(p, regex::icase);  
        string temp, str;  
        while (getline(file, temp))  
            str = str + temp + "\n";  
        vector<string> vec{ "albeit","beige","feint","heir","reign","their",  
            "counterfeit","foreign","inveigh","rein","veil","deign",  
            "forfeit","inveigle","seize","veineiderdown","freight",  
            "leisure","skein","weigheight","heifer","neigh","sleigh",  
            "weighteither","height","neighbour","sleight","weirfeign",  
            "heinous neither surfeit weird" };  
        for (sregex_iterator it(str.begin(), str.end(), reg), end_it; it != end_it; ++it)  
        {  
            if (find(vec.begin(), vec.end(), it->str()) != vec.end())
                continue;  
            cout << it->str();  
            system("pause");  
            auto pos = it->prefix().length();  
            cout << it->prefix().str().substr(pos > 40 ? pos - 40 : 0) << "[> " << it->str() << "<]" << it->suffix().str().substr(0, 40) << endl;  
        }  
      
        system("pause");  
        return 0;  
    }  

练习17.19 为什么可以不先检查m[4]是否匹配了就直接调用m[4].str()?

调用m[4].str()的情况下都有比较苛刻的比较条件。

而且在else中,m[4].str()有三种可能匹配情况。


练习17.20 编写你自己版本的验证电话号码程序。

#include <iostream>
#include <string>
#include <regex>
using namespace std;
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{4})";
	regex r(phone);
	smatch m;
	string s;
	while (getline(cin, s)) {
		for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it) {
			if (valid(*it)) {
				cout << "valid: " << it->str() << endl;
			}else{
				cout << "not valid" << it->str() << endl;
			}
		}
	}
}

练习17.21 使用本节中定义的valid函数重写8.3.2节(第289页)中的电话号码程序。

 

    #include <iostream>  
    #include <sstream>  
    #include <fstream>  
    #include <string>  
    #include <vector>  
    #include <regex>  
      
    struct PersonInfo {  
        std::string name;  
        std::vector<std::string> phones;  
    };  
    bool valid(const std::smatch &m);  
    bool read_record(std::istream &is, std::vector<PersonInfo> &people);  
    void format_record(std::ostream &os, const std::vector<PersonInfo> &people);  
      
    int main()  
    {  
        using namespace std;  
        vector<PersonInfo> people;  
        string filename;  
        cout << "enter input file name:";  
        cin >> filename;  
        ifstream fin(filename);  
        if (read_record(fin, people))  
        {  
            cout << "enter output file name:";  
            string outname;  
            cin >> outname;  
            ofstream fout(outname, ofstream::trunc); //覆盖文件:trunc  
            format_record(fout, people);  
        }  
        else  
            cout << "open file error:" << filename << endl;  
      
        system("pause");  
        return 0;  
    }  
      
    bool valid(const std::smatch &m)  
    {  
        if (m[1].matched)  
            return m[3].matched && (m[4].matched == 0 || m[4] == " ");  
        else  
            return !m[3].matched&&m[4].str() == m[6].str();  
    }  
    bool read_record(std::istream &is, std::vector<PersonInfo> &people)  
    {  
        if (is)  
        {  
            std::string line, word;  
            while (getline(is, line))       //读取一行到line  
            {  
                PersonInfo info;  
                std::istringstream record(line);    //关联流到line,把record绑定到要读取的行line  
                record >> info.name;      //把流中第一个字符串输入到name,这一行的第一个,也就是名字  
                while (record >> word)          
                    info.phones.push_back(word);//把名字后面的电话号码保存  
                people.push_back(info);     //添加一个联系人  
            }  
            return true;  
        }  
        else  
            return false;  
    }  
    void format_record(std::ostream &os, const std::vector<PersonInfo> &people)  
    {  
        std::string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ]?)(\\d{4})";  
        std::regex reg;  
        try {  
            reg.assign(phone);  
        }  
        catch (std::regex_error e)  
        {  
            std::cout << e.what() << "\ncode: " << e.code() << std::endl;  
        }  
        std::smatch m;  
        for (const auto &x : people)  
        {  
            std::ostringstream formatted, badNums;  
            for (const auto &n : x.phones)  
            {  
                for (std::sregex_iterator it(n.begin(), n.end(), reg), end_it; it != end_it; ++it)  
                {  
                    if (!valid(*it))  
                        badNums << " " << n;    //将数据放入流,暂时保存  
                    else  
                        formatted << " " << n;  
                }  
            }  
            if (badNums.str().empty())  
                os << x.name << " " << formatted.str() << std::endl;    //将流中的数据以string的形式放入os流中  
            else  
                std::cerr << "file error: " << x.name << " invalid number " << badNums.str() << std::endl;  
        }  
    }  

练习17.22 重写你的电话号码程序,使之允许在号码的第三部分之间放置任意多个空白符。

"(\\()?(\\d{3})(\\))?([[:blank:]]*)?(\\d{3})([[:blank:]]*)?(\\d{4})"

练习17.23 编写查找邮政编码的正则表达式。一个美国邮政编码可以由五位或九位数字组成。前五位数字和后四位数字之间可以用一个短横线分隔。

#include <iostream>
#include <string>
#include <regex>
using namespace std;
int main()
{
	string code = "(\\d{5})([-])?(\\d{4})?";
	regex r(code);
	smatch m;
	string s;
	while (getline(cin, s)) {
		for (sregex_iterator it(s.begin(), s.end(), r), end_it; it != end_it; ++it) {
			if ((*it)[3].matched || (*it)[1].matched) {
				cout << "valid: " << it->str() << endl;
			}
			else {
				cout << "not valid: " << it->str() << endl;
			}
		}
	}
}

练习17.24 编写你自己版本的重排电话号码格式的程序。

#include <iostream>
#include <string>
#include <regex>
using namespace std;
using namespace std::regex_constants;
int main()

{
	string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
	regex r(phone);
	smatch m;
	string s;
	string fmt = "$2.$5.$7";
	while (getline(cin, s)) {
		cout << regex_replace(s, r, fmt) << endl;
	}
	return 0;
}

练习17.25 重写你的电话号码程序,使之只输出每个人的第一个电话号码。

#include <iostream>
#include <string>
#include <regex>
using namespace std;
using namespace std::regex_constants;
int main()

{
	string phone = "(\\()?(\\d{3})(\\))?([-. ])?(\\d{3})([-. ])?(\\d{4})";
	regex r(phone);
	string s;
	string fmt = "$2.$5.$7";
	while (getline(cin, s)) {
		smatch m;
		regex_search(s, m, r);
		if (!m.empty()) {
			cout << m.prefix() << m.format(fmt) << endl;
		}
	}
}

练习17.26 重写你的电话号码程序,使之多于一个电话号码的人只输出第二个和后续的电话号码。

cout << m.prefix() << m.suffix()<< endl;  

练习17.27 编写程序,将九位数字邮政编码的格式转换为ddddd-dddd。

#include <iostream>
#include <string>
#include <regex>
using namespace std;
using namespace std::regex_constants;
int main()
{
	string code = "(\\d{5})(\\d{4})?";
	regex r(code);
	smatch m;
	string fmt = "$1-$2";
	string s;
	while (getline(cin, s)) {
		cout << regex_replace(s, r, fmt,format_no_copy) << endl;
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值