ページ 11

ファイルの拡張子を判別する方法について

Posted: 2014年5月26日(月) 20:19
by elle
こんばんは。
stringに格納されたファイルパスから拡張子を判別する方法についてお聞きします。
具体的にはそのファイルパスがDXライブラリで使用できる音声ファイルであることを確かめたいと思っています。
(更に具体的に言うと、ドラッグアンドドロップされたファイルが音声ファイルならある処理を、画像ならある処理を、それ以外ならMessageBoxという風にしたいと考えています)
テスト用に下のコードを書きました。

コード:

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

int main()
{
	// str1とstr3が正しいwavファイルのパス
	std::string str1("sth/sdfg/sdf.wav");
	std::string str2("sth/sdfg/sdf.wavv");
	std::string str3("sth/sd.fg/sdf.wav");

	std::regex regSoundFile(R"([^.]+\.(wav|ogg|mp3)$)", std::regex::icase | std::regex::ECMAScript);

	if (std::regex_match(str1, regSoundFile)){
		std::cout << "str1 matched.\n";
	}
	if (std::regex_match(str2, regSoundFile)){
		std::cout << "str2 matched.\n";
	}
	if (std::regex_match(str3, regSoundFile)){
		std::cout << "str3 matched.\n";
	}

	return 0;
}
str1とstr3がマッチすることを期待したのですが、
このコードでは、結果はstr1のみマッチと、str3のようにフォルダ名に「.」が含まれると上手く判定されません。
ピリオドを許容するようにと、

コード:

R"(.+\.(wav|ogg|mp3)$)"
とするとやはり貪欲法のためどれにもマッチしなくなってしまいます。
stringクラスのsubstr()やfind()を使ってもいいのですが、許容する拡張子の種類だけif文内の行数が増え、
あまりスマートではないように思います(case-sensitiveも考慮する必要があります)。
出来るだけ正規表現で判別を実現したいのですが、何かいい方法はあるでしょうか?

Re: ファイルの拡張子を判別する方法について

Posted: 2014年5月26日(月) 20:27
by h2so5
これで正常にマッチすると思います。

コード:

R"(.+\.(wav|ogg|mp3))"

Re: ファイルの拡張子を判別する方法について

Posted: 2014年5月26日(月) 20:34
by elle
>h2so5さん

ありがとうございます!期待通りにマッチしました。
$が蛇足だったのですね。

(追記:解決押し忘れてました。)

Re: ファイルの拡張子を判別する方法について

Posted: 2014年5月26日(月) 20:38
by h2so5
$が入っていると上手くマッチしないのはどうやらgccのバグのようです。
gcc4.9.0以上もしくはclangであれば$が入っていても正常にマッチします。

Re: ファイルの拡張子を判別する方法について

Posted: 2014年5月26日(月) 20:49
by elle
>h2so5さん

あ、すいません、MSVC2013EEを使用してます。
ということはMSVCも同じバグ…ということですね。

Re: ファイルの拡張子を判別する方法について

Posted: 2014年5月26日(月) 20:58
by h2so5
バグというか実装が不完全なのかもしれません。
代わりにboost::regexかboost::xpressiveを使うという手もあります。

Re: ファイルの拡張子を判別する方法について

Posted: 2014年5月26日(月) 21:11
by elle
>h2so5さん

なるほど…。
また正規表現で問題が出るようであればBoostの導入も検討してみます。
ありがとうございました。