C++で淡々とregex.hを使ってみた その3
グループを使いつつ, 繰り返しパターンをあててみる.
パターンは最長のものを選んできてしまうので, 短いものが欲しい場合はパターンを工夫する必要がある. 今回はグループ内の文字にセパレータ(ここでは"aeiou"のいずれか)を含まないようにしている.
http://itdoc.hitachi.co.jp/manuals/3020/30203R7651/IMDS0377.HTM
#include <regex.h> #include <iostream> #include <string> int main(void) { regex_t reg; int errcode = regcomp(®, "[aeiou]([^aeiou]*)[aeiou]", REG_EXTENDED); if (errcode != 0) { char errbuf[100]; regerror(errcode, ®, errbuf, sizeof(errbuf)); std::cout << "regcompile error: " << errbuf << std::endl; regfree(®); return 1; } const std::string target("abcdefghijklhmopqrstuvwxyz"); std::string tmp(target); regmatch_t match[2]; while (true) { errcode = regexec(®, tmp.c_str(), 2, match, 0); if (errcode == REG_NOMATCH) { break; } else if (errcode != 0) { char errbuf[100]; regerror(errcode, ®, errbuf, sizeof(errbuf)); std::cout << "regexec error: " << errbuf << std::endl; regfree(®); return 1; } std::cout << tmp.substr(match[0].rm_so, match[0].rm_eo - match[0].rm_so) << std::endl; std::cout << tmp.substr(match[1].rm_so, match[1].rm_eo - match[1].rm_so) << std::endl; tmp = tmp.substr(match[0].rm_eo); } regfree(®); return 0; }
今回は2回マッチして,
$ ./a.out abcde bcd ijklhmo jklhm
のようになるはず. マッチしたパターンはregmatch_t構造体にスタート位置と終了位置(オフセット)がrm_so, rm_eoとして入っているのでこれを使えば良い. コスト的には微妙だがサンプルでは面倒なのでstd::stringを用いた.