いつもお世話になっております、デメです。先日C++ Boostで正規表現を使用する方法を勉強させて頂きました、その際、C言語の「GNU regex」でも正規表現を実現できる事が分かりましたので、勉強しているのですが、設定方法/インストール方法/使用方法がいまいち分かりません。分かりやすいWebページがあったら教えてください。宜しくお願い致します。
正規表現を扱う regcomp() は POSIX2 標準 (UNIX 標準) なので、
UNIX 系の OS なら標準で使えますし man もあります (Linux man page 等を参照)
POSIX 正規表現の解説
http://sometime.minidns.net/~ccgi/posix_regex.html
VisualC++ は POSIX ではない (一部 POSIX な関数も用意されています) ため、
標準では正規表現系関数は用意されていないわけです。
ということで GNU regex を紹介したわけですが、既に GNU Rx に置き換わっています。
GNU Rx 日本語解説+VisualC++ Porting とかなら
http://www.sip.eee.yamaguchi-u.ac.jp/kou/regex.html
リンク先は、読めばそれ以上の解説は不要なくらいよく書けてる。見習わないと。
何かまだわからなければ聞いてください。
tetrapod様、返信ありがとうございます。URLのページを見たのですが、サンプルがないため使用方法が分かりません。Webでサンプルがないか調べたのですが、見つかりません。ご教授お願い致します。
いや、サンプルあるじゃないですか。
> regex_t preg;
> regmatch_t pmatch[4];
> regcomp(&preg, "([[:alpha:]]:)?(.*[\\/])?([^\\/]+)", REG_EXTENDED|REG_NEWLINE);
> regexec(&preg, str, 4, pmatch, 0);
> regfree(&preg);
あとはリファレンスで各引数の意味を調べれば十分かと思いますが…
シャノンさん、ありがとうございます。installVC6.batでライブラリをインストールしたのですが、コンパイルエラーになってしまいました。ご教授のほど宜しくお願い致します。
---
コンパイル中...
sample.cpp
C:\Documents and Settings\suzuki_tadahiro\デスクトップ\vc_chk_reg\test\sample.cpp(22) : error C2660: 'regcomp' : 関数が不正な 3 個の実引数をともなって呼び出されました。
C:\Documents and Settings\suzuki_tadahiro\デスクトップ\vc_chk_reg\test\sample.cpp(23) : error C2065: 'str' : 定義されていない識別子です。
C:\Documents and Settings\suzuki_tadahiro\デスクトップ\vc_chk_reg\test\sample.cpp(24) : error C2660: 'regfree' : 関数が不正な 1 個の実引数をともなって呼び出されました。
cl.exe の実行エラー
sample.obj - エラー 3、警告 0
リンク先の「C++ からの利用」の項目を参照のこと。
またはソースファイル名を .c にして C ソースにする (cpp ではだめ) 。
----rxtest1.c----
#include <stdio.h>
#include <rxposix.h>
int main() {
regex_t preg;
regmatch_t pmatch[3];
const char str[]="3.21E-001";
regcomp(&preg, "([0-9]*\\.[0-9]*[Ee][+-])0*([1-9][0-9]*)", REG_EXTENDED|REG_NEWLINE);
regexec(&preg, str, 3, pmatch, 0);
printf("[%.*s]\n", pmatch[1].rm_eo-pmatch[1].rm_so, &str[pmatch[1].rm_so]);
printf("[%.*s]\n", pmatch[2].rm_eo-pmatch[2].rm_so, &str[pmatch[2].rm_so]);
regfree(&preg);
return 0;
}
うまくいったようですよ。
tetrapodさん、ありがとうございました。
拡張子を.cにして、#pragma comment(lib, "librx.lib")をソースに追加したら動きました。
.cppでは、以下を追加すれば動きそうなのですが、リンク時にエラーになってしまいます。.cppでは動作しないのでしょうか??
---
extern "C" {
#ifndef __STDC__
#define __STDC__
#endif
#include <rxposix.h>
}
---
はて?当方では rxtest2.cpp で問題なく動きましたが...
リンクエラーになっているエラーメッセージは C++ 修飾名でしょうか、それとも C 関数名?
前者ならタイプミスがあるはず。
後者なら正しく librx.lib が見つかっているかどうかチェック。
tetrapodさま、ありがとうございます。C++は、あとでもう一度確認します。
さて、C言語で正規表現は動いたのですが、()グループを変数に格納する方法が分かりません。ご教授のほど宜しくお願い致します。
printf("[%.*s]\n", pmatch[1].rm_eo-pmatch[1].rm_so, &str[pmatch[1].rm_so]);
printf("[%.*s]\n", pmatch[2].rm_eo-pmatch[2].rm_so, &str[pmatch[2].rm_so]);
え゛ー?そこまで面倒見ないといけませんか?自明ぢゃん。
# memcpy でも strncpy でも sprintf でも、どれでもお好みで。
むしろ第三者読者のためにこっちをフォローしたりしてみたいです。
regcomp(&preg, ...);
regmatch_t* pmatch=new regmatch_t[preg.re_nsub+1];
regexec(&preg, str, preg.re_nsub+1, pmatch, 0);
regcomp は re_nsub に () 部分正規表現の数を返すので、正規表現全体にマッチするべき1つを含めて
regmatch_t を re_nsub+1 個用意すると吉かと。
ツイート | ![]() |