正規表現に関する世界観です。
正規表現は、文字とパターンをマッチングさせる手段。多くの場合、言語のライブラリやUNIXなどのOSのコマンドで利用できる。
主に、検索と置換のために使われる。「どんな文字に一致させるか」を考えながら、パターンマッチングを行う。また、特殊文字(改行やタブなど)はエスケープシーケンスと言って、バックスラッシュ(\)によってマッチングさせることができる。PerlやRubyなどでは、マッチングした場合としなかった場合において条件分岐したり、マッチングした部分を取り出して変数に格納したりすることもできる。
正規表現は一見すると記号的で読みにくさを感じるかもしれないが、慣れるととても便利である。特に、テキストエディタにgrep置換機能が付いている時は、正規表現を使うことで膨大なファイルを一瞬にして編集することができる。
たとえば、以下のようにすることで、*から始まる全ての行にh3タグを付加できる。
検索:
^\*(.*)$
置換:
<h3>\1</h3>
さらに以下のようにすれば、<以外の文字から始まる全ての行にpタグを付加できる。
検索:
^([^<].*)$
置換:
<p>\1</p>
正規表現の高度な実例や記法の一覧は以下のリンク先が参考になります。
正規表現は、書くのがちょっと面倒でも、正規表現を使って置換をした方が、確実で、速いです。
たとえば、全ての行に<p> ~ </p>をつけたいなら、^(.*)$を<p>\1</p>で置換します。
こうすることで、確実で簡単で速いだけではなく、たくさんのファイルを置き換える時にも管理しやすくなります。
しかしながら、間違えることもあるので注意しましょう。たとえば.*でタグの中身だけを置換したい時に、マッチする部分が最小マッチではなく最大マッチになっていると、タグの外側までマッチしてしまって、<p>から</p>までを置き換えたいのに<p>~</p>~<p>~</p>までを置き換えたりすることがあります。このような時には.*ではなく[^<]*でマッチさせます。
そのため、たくさんのファイルを置換する時は気を付けましょう。バックアップを取ることも大切です。
正規表現とエスケープシーケンスの基本。
正規表現 | 説明 |
---|---|
.* | 任意の文字列。 |
.*? | 任意の文字列の、最小限のマッチ。 |
* | 0回以上の繰り返し |
+ | 1回以上の繰り返し |
? | 0回または1回(あるかないか分からない時に使う) *?、+?、??のようにつけた場合は、最長一致ではなく最短一致を行う。 |
{n} | n回の繰り返し |
{n,} | n回以上の繰り返し |
{n,m} | n回以上m回以下の繰り返し |
^ | 行の先頭 |
$ | 行の最後 |
. | 任意の一文字。 |
\w | 英単語を構成する文字。 |
\W | 英単語を構成する文字以外。 |
\d | 数字。 |
\D | 数字以外。 |
[a-z] | aからzまで。 |
(hoge) | (~)内は一文字であるかのように扱われる(グループ化)。 置換後の文字列を取り出すためにも使う(キャプチャ)。 |
(foo|bar) | 指定したパターンのどれか。 |
~ | 最後に使った正規表現のパターンにマッチする。 |
& | 置換文字列で、パターンにマッチした部分全体を表す。 viでは :%s/Hello/&, Assy/ などとできる。 |
\uまたは\l | 次の文字を大文字あるいは小文字に変える。 |
\Uまたは\L \eまたは\E | 置換文字列の最後の位置までか、あるいは\eか\Eの位置までを、文字を大文字あるいは小文字に変える。 たとえば、viなら:%s/Gnome/\U&/で、GnomeをGNOMEに変えることができる。 |
\n | 改行。 |
\r\n | 改行。Windowsの場合は\r\nを使う。 テキストエディタによってはWindowsの場合でも\nで改行にマッチすることが多い。 |
\s | スペース。 |
\t | タブ。 |
[~] | いずれかの文字。 |
[^~] | それ以外の文字。 |
詳しくは入門vi 第6版やサルにもわかる正規表現入門を参照のこと。
( ~ )でくくったパターンは、\1や\2として、置換後のテキストに含めることが出来る(キャプチャ)。
たとえば、
置換前 | 置換後 |
---|---|
(.*)\t(.*)\n | <h2>\1</h2>\n<p>\2\n |
などと置換出来る。
エディタによっては( ~ )ではなく\( ~ \)のように\が要る場合もあるので注意が必要。xyzzyでは\が必要だが、サクラエディタでは\は必要ない。サクラエディタの場合、複数行の置換には対応していないので注意が必要。(後日注記:基本正規表現と拡張正規表現の違いがあるのかもしれない。不勉強なので分からない。申し訳ない。)
キャプチャせずにグループ化だけをしたい場合は(?:pattern)という記法を行う。
viでも\が必要。viではexコマンドを使って以下のように置換できる。
:%s/\(Ho*ge\) or \(Fu*ga\)/\2 or \1/
たとえばHooooge or FuuuugaをFuuuuga or Hoooogeに置換できる。
\( ~ \)でくくられたパターンは、ホールドバッファと呼ばれる特別な領域に保管され、1行の中に含まれる9つのパターンまで、\1や\2などの形で保存・利用できる。
入門vi 第6版も参照のこと。
特殊文字をそのまま文字としてマッチさせたい時は、\.のように\をつけてエスケープする。
Perlなどでの正規表現の修飾子は/pattern/mのようにパターンの最後に付加して使う。viでマッチする全ての文字について置換を行う場合は:%s/old/new/gなどとする。
Perlでの正規表現の置換は、s/old/new/とする。修飾子/gを使ってすべてのマッチする場所に対する一括置換を行う場合はs/old/new/gとする。
Perlでの一括置換は、=~を使って
$str = "I am a Linux user. Linux is a good OS.\n"; $str =~ s/Linux/FreeBSD/g; print $str;
などと記述すればよい。
デフォルトでは正規表現は一回のマッチングしか行われないが、/gを使うとマッチする全ての場所にマッチや置換を行うことができる。
/sを使うと、.が改行にもマッチするようになる。
また/mを使うと、文字列は行ごとのリストになって、行ごとに^や$がマッチし、繰り返し処理が行える。
また便利なのは/eで、マッチした文字列ごとにPerlの関数をかけることができる。置換後として記述された文字列をPerlのコードとして実行できる。たとえば、
$str =~ s/.*\n/chomp($&) . ","/eg;
などとできる。
/xを使うと改行やコメントができるようになるため、正規表現が長くなっても見やすい記述をすることができる。
Perlも参照のこと。
2023.03.24編集
正規表現以外の一括置換に使えるUNIXのコマンドとして、trコマンドがある。a-zをA-Zに置換するように、置換する文字をまとめて書くことができることが特徴。
Perlなどでも、s///記法による正規表現のパターンマッチングの一括置換のほかに、tr///記法を使ってtrコマンドと同様の方式で一括置換をすることもできる。
$str =~ tr/a-z/A-Z/;
詳しくはPerl言語プログラミングレッスン 入門編が参考になる。
UNIXコマンド(ユーザープログラム)も参照のこと。
2023.03.24
Perlなどのプログラミング言語だけではなく、UNIXのコマンドやサクラエディタなどからも検索・置換のために使う。
大量のファイルを編集する際には正規表現は必須である。
使うツールによって正規表現に若干の差異があったり、サクラエディタでは複数行の検索・置換ができないなど制限もあったりするので、使うツールをよく選ぶこと。
大量のテキストファイルを編集するためには、正規表現は必須です。僕は、xyzzyと言うテキストエディタを使っています。