LoginSignup
31
12

More than 5 years have passed since last update.

gccの正規表現がバグだらけという話

Last updated at Posted at 2017-01-25

その1

例えば、次の簡単なコード(抜粋)をgcc 4.9.2で実行してみましょう。

string s("test");
smatch m;
regex re(R"([A-Z_a-z]+)");
if (regex_search(s, m, re)) {
    cout << m[0] << endl;
}
else {
    cout << "Not matched" << endl;
}

Wandbox

Not Matched

!!!???
どうなってるの???

これ、"_" の場所を変えたりしたらマッチするようになるんですよ。
なぜか?
わからない。わかりたくもない。
こんなファッキンなバグが、gcc 4.9.2 まで残ってるんですよ。
4.9.3 では直っていました。

その2

今度は、これをgcc 4.9.2 で実行してみましょう。
文字クラスにマッチさせるだけの簡単な正規表現です。

string s("~");
smatch m;
regex re(R"([~\-_])");
if (regex_search(s, m, re)) {
    cout << m[0] << endl;
}
else {
    cout << "Not matched" << endl;
}

Wandbox

Not Matched

えぇ…。
まあ、気を取り直して、4.9.3 で動かしてみましょう。
Wandbox

terminate called after throwing an instance of 'std::regex_error'
  what():  regex_error
Aborted

なんでだよ!
このエラー、どうやら"\-"のエスケープが効いていない("\]"は大丈夫なようです)ことによるもののようで、gcc 6.1.0 でも直っていませんでした。
(やれやれ)
gcc HEAD 7.0.1 20170123 (experimental)では直っていました。
使えるか!!

まあ、こちらのほうはその1みたいに完全に意味不明というわけではなく、"-"のエスケープをあきらめて、文字クラスの先頭か末尾に持って行けばいいので、まだ対処可能です。

結論

gccを窓から投げ捨てましょう。
Clangでは、当然のことながら、どちらもOKです。

まあ、投げ捨てられない場合、できるだけ新しいものを使って、文字クラスにハイフンそのものを入れる場合は、エスケープせずに先頭か末尾に入れましょう。

31
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
12