はじめに
正規表現を勉強していて、\(
...\)
とか\{
...\}
などの表現が多くてうんざりしているとか、よーわからんとか、自分で試してもうまく実行されないとかで困っていませんか?私はよく困っていました(笑)
そんな方は、ぜひ拡張正規表現を試してみてはいかがでしょうか!
というのが本記事の内容です。以下、具体的な内容に入りたいと思います。
拡張正規表現を利用する
拡張正規表現はLinuxでは例えばegrep
grep -E
sed -r
などで利用することができます。
これによって\(
...\)
が(
...)
、\{
...\}
が{
...}
と書けば済むようになるので、コマンドがスッキリして見通しが良くなります。
また、+
?
|
といったメタ文字もそのまま利用することができます。(grep
やsed
の場合、通常の正規表現で使用するには、\+
\?
\|
にする必要あり)
これらの結果として多くの場合で、後の章で示す早見表と同じ書き方で正規表現を利用できるようになります。
( *2(最短一致) のものや、一部の\アルファベット
のものは、grep -P
とかじゃないと使えないものもあります)
そして拡張正規表現の使い方に慣れてきたタイミングで、
今度は\(
...\)
や\{
...\}
を使った通常の正規表現の使い方にも慣れるのが、正規表現の勉強に息詰まっている人にとってはおそらく良いのではないかと個人的に思っています!
通常の正規表現と拡張正規表現の違いについてはこの記事にわかりやすくまとまっているので、ぜひご覧ください。基本正規表現 (BRE) と拡張正規表現 (ERE)
その他のコマンドで拡張正規表現を利用する
(そのような場面があるかはわかりませんが、)もしegrep
grep
sed
以外のコマンドで拡張正規表現を利用できるか調べたい場合は、そのコマンドに拡張正規表現を利用するためのオプションがあるかどうかを調べるのが良いです。例えば、
-
「拡張正規表現」という文言が書かれたオプションがないか(ネットで調べる)
-
コマンドのヘルプで「extended regexp」や「extended regular expression」と書かれているオプションがないか
などを探せば、判断できるかと思います。
拡張正規表現を利用する上での注意点
拡張正規表現を利用する際には、
-
拡張正規表現(ERE)は通常の正規表現(BRE)の完全な上位互換ではないこと
-
拡張正規表現(ERE)と通常の正規表現(BRE)以外にも正規表現の種類があること(EREでも使えない正規表現が存在すること)
を理解した上で利用するのが良いです。
1つ目に関しては、例えば次のような3つの注意点が挙げられます。
**1. `\`をつけると逆にうまくいかなくなる**
拡張正規表現を利用する場合、通常の正規表現(BRE)で使用していた`\`をそのまま残しておくと、逆にプログラムがうまく実行されなくなります。 (例えば、`\(`...`\)`や`\{`...`\}`のままにしておくとうまくいかない)このことから、拡張正規表現(ERE)はBREを包括したものではなく、全く別の表現方法なのだという認識を持っていた方が良いのかもしれません。
**2. 後方参照が利用できない場合がある**
私自身は詳しくないのですが、以下のような記述を見つけることができました。 この点からも拡張正規表現はBREの完全な上位互換とは言えません。(参照:**[どのUNIXコマンドでも使える正規表現](https://qiita.com/richmikan@github/items/b6fb641e5b2b9af3522e)**) **2. ERE(拡張正規表現)メタ文字セット**
**a-1. マッチを掛ける文字列(置換前の文字列)のメタ文字一覧(ブラケット外部)** BREを拡張して使えるメタ文字が増えている(`+`、`?`、`|`)が、純粋な上位互換ではないので注意。具体的には、バックスラッシュでエスケープしていた括弧類のメタ文字(`\(`、`\)`、`\{`、`\`})がバックスラッシュ不要になっている点、そして**後方参照が保証されていない(実際に使えない実装がある)**点である。
(補足すると、「マッチを掛ける文字列」は例えば`grep " ~ " `の`" "`内側部分、「置換前の文字列」は例えば`sed 's/ ~ / xxx /'`の`~`の部分、「ブラケット外部」は`[` `]`の内側でない事を指します。)
**3. それぞれ適材適所がある**
**[基本正規表現 (BRE) と拡張正規表現 (ERE)](https://entree.hatenadiary.org/entry/20141126/1417016871)**にも記載されている通り、使用する場面がコマンドライン上かスクリプト上かに応じてそれぞれEREを使うか、BREを使うかを分けるのが望ましいようです。(EREは後者のシチュエーションだと`\`を付けなければいけないメタ文字の種類が増えるため)
2つ目に関しては、BREやEREの他にもGNU拡張正規表現メタ文字セットやPerl拡張正規表現メタ文字セット、JavaScript拡張正規表現メタ文字セットなど、様々な正規表現が存在します。
たとえばgrep
の場合、grep -P
でPerl拡張正規表現が利用できるようになります。grep -E
とgrep -P
では使えるコマンドに差があります。(早見表参照)
正規表現早見表
[引用:正規表現一覧]
- (補足)
\<
や\>
はアルファベットなどの文字列が、スペースや記号で区切られている場合に効果を発揮します。例えば、egrep "\<a"
と書けば、aで始まる単語をもつ文字列が出力され、egrep "a\>"
と書けば、aで終わる単語をもつ文字列が出力されます。
その他正規表現に関するメモ
(私自身の備忘録的な意味合いが強いです🙇♂️)
- 正規表現の種類に関してまとまっている記事
・どのUNIXコマンドでも使える正規表現(拡張正規表現に関してはこちらに詳しくまとまっています)
・正規表現 - Bash入門(個人的にわかりやすかったので載せました)
・正規表現の基本(Javaの正規表現。参考までに)
- 正規表現の使用例に関する記事
・正規表現まとめ(可視化ツールで視覚化しながら説明してくれているので、わかりやすいです)
・基本的な正規表現一覧 | murashun.jp(各メタ文字の使用例がシンプルにまとめられています)
・正規表現パズル(問題形式でいろんな使用例が載っています)
【正規表現の可視化ツール】
上の記事からの引用ですが、各メタ文字の動きを知りたい時などに便利です。
・regular expression101(PHP, JS, Python, Golang)
・Regexper(正規表現の可視化)
おわりに
シンプルに終わらせるつもりが意外と長くなってしまいましたが、いかがでしたでしょうか。
私自身もまだまだ正規表現に関して勉強が足りていないので、今後また良い記事や必要な内容が出てきたら随時追加したいと思っております。
ご覧いただきありがとうございました!🙇♂️🙇♂️