17.3节练习

来源:互联网 发布:手机验钱软件 编辑:程序博客网 时间:2024/04/29 14:01

练习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
原创粉丝点击