次は Java のクイズ。
String s = "いっぱい";
s.replaceAll("^い", "お");
System.out.println(s);
これで何が出力されるだろうか?
String の replaceAll() メソッドは、第1引数にマッチした全ての箇所を第2引数に置換する。しかし、第1引数をよく見ると、文字列の先頭を意味する正規表現 の「^」がついている。つまり、先頭の「お」だけが置換される。
というわけで、答えは「おっぱい」・・・ではない。
s.replaceAll() は、s 自身が示す文字列は置換せず、置換した結果を戻り値として返すのだ。ここでは戻り値が受け取られていないから、出力されるのは最初に s に代入された「いっぱい」である(※)。
★
正規表現は便利だが、複雑になれば読みにくくなる。このため、プログラマは、正規表現を使った処理が思うように動かない場合、まず正規表現の書き方を疑うものだ。うまくいくまで何度も書き方を見直しては動作確認を繰り返すだろう。
たしかに、正規表現が間違っているという可能性は大きいのかもしれない。しかし、原因が全く別である可能性もある。もしそうなら、正規表現をいくら見直しても解決しない。そして、それに気がつかないなら、長時間無駄に悩んでしまうことになる。
私も上記の例のように replaceAll() の戻り値を捨ててしまうという過ちに気がつかず、無駄に悩んだことがある。また、他の人が同じ原因で悩んでいるところも目撃したことがある。
後から考えれば単純なミスなのだが、そのときは先入観のために全く気がつかないのだ。
★
このように、プログラミングをしていると、先入観のためにバグの原因が見つからないということが時々ある。すぐ近くに単純な原因が見えているのに、それに気がつかないのだ。ちょっと視野を広くして見ればいいだけの話なのだが、人間、それが難しい。
ある程度悩んで解決しない場合には、環境を変え、気分をリフレッシュしてから再度取り組むようにするといいだろう。例えば、休憩を取ったり、他の作業をするなどして、時間を置いてから考え直してみると、原因に気がつくことがある。翌日に持ち越す余裕があれば、よく寝てから翌朝考えるのもいい。あるいは、ソースコードを印刷して紙の上で読むことで、見つかるようなこともある。
もちろん、他の人に相談するのも有効である。上記のような初歩的なミスを他人に指摘されるのは恥ずかしいかもしれない。しかし、そんなのは誰にでもあること。笑い話にすればよい。悩んで無駄な時間を過ごすよりはずっといいだろう。
※Java の String は文字列定数を示すクラスなので、自分の示す値自体を変更するメソッド(Ruby流に言えば「破壊的メソッド」)を持たない。これは、Java の基礎的な知識だ。しかし、他のプログラミング言語では、この種のメソッドは破壊的になっている場合も多く、ケアレスミスに繋がりやすい(→ 「新しいプログラミング言語を学ぶということ」 )。
■関連記事
・真夜中のコード
・怖いこと
詳説 正規表現 第2版
posted with amazlet
on 06.09.30
Jeffrey E.F. Friedl 田和 勝
オライリー・ジャパン
売り上げランキング: 19,679
オライリー・ジャパン
売り上げランキング: 19,679
おすすめ度の平均:
正規表現を学びたい人が買う第一冊目に最適著者の努力に脱帽
小松原 明哲
丸善
売り上げランキング: 22,009
丸善
売り上げランキング: 22,009
おすすめ度の平均:
入門的な本