yucatio@システムエンジニア

趣味で作ったものいろいろ

RubyMineの正規表現チェックがrubyのString#matchと挙動が違う件

RubyMineには文字列が正規表現にマッチするか調べる機能があります。

1. 正規表現にカーソルを移動し、 電球マークまたはoption+エンターキー(windowsの場合はalt+エンターキ)を押す。

f:id:yucatio:20180817230427p:plain

2. Check RegExpを選択する

f:id:yucatio:20180817230610p:plain

3. Sample:にテストしたい文字列を入力します

f:id:yucatio:20180817231821p:plain

4. マッチする場合はMatches!と表示され、緑色の背景になります

f:id:yucatio:20180817231201p:plain

マッチしない場合はNo matchと表示され、赤色の背景になります

f:id:yucatio:20180817231413p:plain

部分マッチに対応していない

とても良い機能を見つけたと思っていたのですが、\.txt$sample.txtにマッチしません。

f:id:yucatio:20180817232019p:plain

もちろんrubyのプログラムを実行すると、マッチします。

# テキストファイルの正規表現
text_file_regex = /\.txt$/

puts text_file_regex =~ 'sample.txt' ? 'テキストファイルです' : 'テキストファイルではありません'
# => テキストファイルです

色々動作を確かめたところ、正規表現にマッチする部分以外が文字列に含まれると'No match'が表示されるようです。

f:id:yucatio:20180817232212p:plain

Check RegExpは入力全体に正規表現がマッチするか調べる機能

この件に関しては、すでにIssueがあがってました。

https://youtrack.jetbrains.com/issue/RUBY-15550

コメントを読むに、このRubyMineのCheck RegExpは、JavaのString#matches (もしくはPattern#matches)と同様の結果を返すようになっているようです。

JavaのString#matchesは、こちらの記事にあるように、

Javaのmatches()が期待する動作にならない落とし穴 | 読書とプログラミングを中心とした覚書ブログ

matches()では正規表現が入力全体に完全にマッチするか確認するという動作になります。

とのことです。

RubyMineはJavaIDEであるIntellijを元に作られていると思われますが、RubyのmatchとJavaのmatchesでの挙動の差異によりRuby開発者にとって思わぬ挙動となっています。

あとがき

とても良い機能を見つけたと思ったのですが、rubyのmatchと異なる結果を返すので、Check RegExpは個人的には「使えない」と感じました。

Issueは4年前のもので、未だに対応していないということは、今後もこのままなのでしょう。

環境