正規表現と grep・sed

プログラムを勉強していると「正規表現」という言葉が出てきます。プログラミング言語の仕様の一部だったり、テキストエディタの編集機能だったりします。処理系によって少し振る舞いが違うこともありますが、文法は大体同じなので覚えておきましょう。

簡単な例

正規表現は文字列のパターンを表現する方法です。「習うより慣れろ」ということで早速サンプルを見ていきます。

これは英数字の文字列を意味する正規表現です。詳しく見ていくと、「a-z」は「文字コードの “a” から “z” までのいずれか」を意味します。「a-zA-Z0-9」で「小文字または大文字の英字または0〜9の数字のいずれか」を意味します。「[ ]」はカッコの中に指定された文字のいずれか1文字を示します。「+」は直前に指定されたパターンの「1文字以上の連続」を示します。まとめると「英字または数字が1文字以上連続した文字列」という意味になります。例えば、正規表現 [a-zA-Z0-9]+ は文字列 Osaka に “マッチする” という言い方をします。Osaka の文字列が正規表現が示す文字パターンに当てはまるからです。文字列 O-saka は記号の “ー” を含んでいるので “マッチしない” ということになります。

正規表現とは

正規表現とは何なのか、ぼんやりとでもイメージできたでしょうか? 少し退屈かもしれませんが説明を続けます。

  • 文字クラスの略記法

先程の例で英数字の定義を見ましたが、\w と省略して書くこともできます。同様に数字や空白(タブや改行も含む)を示す記法もあります。

記法 等価なクラス 否定形 等価な否定クラス
\d(数字) [0-9] \D(数字以外) [^0-9]
\w(単語) [a-zA-Z0-9_] \W(単語以外) [^a-zA-Z0-9_]
\s(空白文字) [ \r\t\n\f] \S(空白文字以外) [^ \r\t\n\f]
  • メタキャラクタ

正規表現を書くときに特別な意味を持つ記号があります。代表的なものを書いておきます。

. 改行文字(\n)を除く任意の1文字。
| 選択を意味し、例えば a|b は「a または b」の意味。
* 直前のパターンが0回以上繰り返すことを意味する。.* で任意の文字列(空文字列を含む)という意味になります。
+ 直前のパターンが1回以上繰り返すことを意味する。
^ 行頭を意味する。行頭に存在する文字列にマッチさせたいときに使う。
$ 行末を意味する。行末に存在する文字列にマッチさせたいときに使う。
[ ] 文字の集合を表す。これを文字クラスと呼ぶ。[abc] は a|b|c と同義。
[^ ] ^ が [ ] 内の先頭にあるとき、[ ] の文字集合の否定を示す。^ を文字として表現したいときは [ ] 内の2文字目以降に書く。
\ メタキャラクタの意味を打ち消して通常の文字として扱う。
  • もっとサンプル

メタキャラクタを使った例を見ていきましょう。この様なデータがあったとします。

正規表現の Osaka は1,2,3行にマッチします。Os[a@]ka とすると1,2,3,4行にマッチします。^Osaka は行頭に該当文字列がある1,2行に、Osaka$ は行末にある 1,3行にマッチします。^Osaka$ は1行にだけマッチします。Oo+saka は5行にマッチします。Oo*saka は1,2,3,5行にマッチします。

grep

grep は Linux/Unix に古くからあるコマンドで、Windows WSL や Mac のターミナルには標準で入っています。Windows の Powershell で動作するものも探せばあるかもしれません。基本的な使い方はこうです。

ファイル名を省略すると標準入力に対して処理を行います。検索パターンは正規表現が使えます。先程の Osaka 等の文字列をテキストファイル data.txt に保存したとしましょう。同じディレクトリでこのコマンドを実行してください。

^が指定されているので行頭に Osaka がある行だけがマッチして出力されています。grep は大量のテキストデータを検索するのに頻繁に使われます。

/etc には大量のファイルがありますが、目的のファイルをすぐに見つけられます。この例ではファイル名に sys を含むファイルが一覧表示されます。

sed

sed もやはり古くからあるコマンドです。

ファイル名を省略すると標準入力に対して処理を行います。スクリプトには色々なコマンドがありますが最もよく使われる “s/検索パターン/置換文字列/” を覚えておくだけでも強力なツールになります。検索パターンには正規表現が使えます。data.txt と同じディレクトリでこのコマンドを実行してください。

正規表現 Osaka がマッチする1,2,3行目の Osaka が Tokyo に置換されました。スクリプトの Osaka のところを ^Osaka や Oo+saka にするとマッチしたところだけが置換されます。この機能を使うとテキストエディタで面倒な置換作業が1コマンドでできてしまいます。Excel の表データを CSV 形式で保存し、sed コマンドで加工したりとか様々な使い方ができます。

最後に

正規表現も sed、grep コマンドの使い方も、ここに書いたのはごく一部です。詳細を勉強するのは実際に必要になった時で構いませんが、状況によってはとても強力なツールになるので、このような方法があることは知っておいてください。

コメント