Hatena::ブログ(Diary)

GANAwareはてな版 RSSフィード Twitter

2013-07-02

正規表現で [a-[:alpha:]] の意味って?

C++11仕様に対する疑問

C++11正規表現 (std::regex_constants::ECMAScript 時) の仕様ECMA-262 の文法を次のように微妙に変更したものとなっています

ClassAtom ::
	-
	ClassAtomNoDash
	ClassAtomExClass
	ClassAtomCollatingElement
	ClassAtomEquivalence
ClassAtomExClass ::
	[: ClassName :]
ClassAtomCollatingElement ::
	[. ClassName .]
ClassAtomEquivalence ::
	[= ClassName =]
ClassName ::
	ClassNameCharacter
	ClassNameCharacter ClassName
ClassNameCharacter ::
	SourceCharacter but not one of "." "=" ":"
(ドラフト n3337.pdf より)

そして ECMA-262 の正規表現の文字クラス周りの文法はだいたい以下のような感じになっています

CharacterClass ::
	[ [lookahead ∉ {^}] ClassRanges ]
	[ ^ ClassRanges ]
ClassRanges ::
	[empty]
	NonemptyClassRanges
NonemptyClassRanges ::
	ClassAtom
	ClassAtom NonemptyClassRangesNoDash
	ClassAtom - ClassAtom ClassRanges
NonemptyClassRangesNoDash ::
	ClassAtom
	ClassAtomNoDash NonemptyClassRangesNoDash
	ClassAtomNoDash - ClassAtom ClassRanges
ClassAtom :: (ここは C++11仕様で変更される)
	-
	ClassAtomNoDash
ClassAtomNoDash ::
	SourceCharacter but not one of \ or ] or -
	\ ClassEscape
ClassEscape ::
	DecimalEscape
	b
	CharacterEscape
	CharacterClassEscape
(Standard ECMA-262 より)

ここで、強調した部分、つまり以下の部分

ClassAtom ::
	ClassAtomExClass
NonemptyClassRanges ::
	ClassAtom - ClassAtom ClassRanges
NonemptyClassRangesNoDash ::
	ClassAtomNoDash - ClassAtom ClassRanges

を素直に解釈すると、例えば次のような正規表現は文法上正しいということになります

[a-[:alpha:]]
[[:alpha:]-a]
[[:alpha:]-[:alpha:]]

文法上は正しいといっても、何を表現しているのか意味がよくわかりません。

現実の実装では?

例えば、Boost C++ Libraries ではテストケース (test_sets.cpp) 内で、以下のようなテストをしており、

   TEST_INVALID_REGEX("[a-[:alpha:]]", boost::regex::extended);

問題となる正規表現記述できないことを確かめています

また、OS X Mountain Lionclang-425.0.28 では、

#include <regex>
#include <iostream>

int main() {
	std::locale::global(std::locale("C"));
	std::regex re("[a-[:alpha:]]");
	std::cout << std::boolalpha << regex_match("a", re) << std::endl;
	std::cout << std::boolalpha << regex_match("b", re) << std::endl;
	return 0;
}

上記のソースを -std=c++11 -stdlib=libc++ でコンパイルして実行すると

true
false

が出力されます。なにが起こったのかよくわかりません。

また、Visual Studio 2012 Express では上記のソースを実行すると std::regexコンストラクタ内で std::regex_error 例外が .code() == std::regex_constants::error_range で throw されます

まとめ

というわけで、この問題は C++11仕様の間違いとして解釈するのが良いと思います

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/ganaware/20130702/1372737739