【正規表現】括弧の中身を取得しないようにする方法(例題あり)

【正規表現】括弧の中身を取得しないようにする方法(例題あり)

今の業務では他言語のソースコード解析や文書解析などを行うことが多く、その度に正規表現とPandasを使って頑張って業務をこなしています。正規表現って慣れないとほんとうに難しすぎる…

そこで今回は、業務でお世話になりまくった「正規表現で括弧(かっこ)の中身を取得しない方法」をご紹介します。

結論:括弧の中身を取得しないやり方

正規表現では基本、取得したいパターンは括弧でくくることで取得できます。

逆に、括弧の中身を取得したくない場合には、括弧の最初に「?:」をつけることで 回避することができます。

(?:取得したくないパターン)

簡単ですね。

でも、これだけではちょっと分かりにくいなぁと思う方がいると思うので、例題をご紹介します。

正規表現の例題:PHPコードから関数名を取得する

下記のようなPHPのコードがあるとします。(関数の中身は必要ないので省略しています。)

public function public_hoge() { 関数の処理 }
protected function protected_hoge() { 関数の処理 }
private function private_hoge() { 関数の処理 }

このようなテキストがあった時、コードにある関数名(public_hoge、protected_hoge、private_hoge)を取得する正規表現を作ってみましょう。

いったん正規表現を作ってみる

関数名を取得する正規表現を簡単に書くと、このようになるかと思います。

(public|protected|private) function ([^\(]+)

(public|protected|private)」の縦棒「|」で区切っている部分は「または」という条件です。
publicか、protectedか、privateどれかが先頭に付いているものを取得します。

後半の「([^\(]+)」は、括弧開き「(」を除く1文字以上の文字列 を指しています。

参考サイト:
正規表現:複数のパターンのどれかにマッチする
正規表現を使って「〜以外」をマッチさせてみる


さて、上の正規表現では 括弧を2つ使用しているため、関係のないpublicやprotectedなども取得されてしまいます。

実際にPythonコードで確認してみると、publicやprotectedも取得されてしまいました。

import re

text = """
public function public_hoge() { 関数の処理 }
protected function protected_hoge() { 関数の処理 }
private function private_hoge() { 関数の処理 }
"""

# 正規表現パターンを指定
pat = re.compile("(public|protected|private) function ([^\(]+)")

# 条件に合致したものを全て取得
print(pat.findall(text))


# --------- 実行結果 ---------
[('public', 'public_hoge'), ('protected', 'protected_hoge'), ('private', 'private_hoge')]

もちろん、上記の正規表現で2つ目の値を取得すれば関数名が取れますが、それは美しくありませんね。

そんな時に、正規表現で括弧の中身を取得しない方法を用いて、publicなどを取得しないようにします。

正規表現を修正

冒頭で説明した通り、括弧の最初に「?:」をつけることで取得されることを防ぐことができます。

変更前: (public|protected|private) function ([^\(]+)
変更後: (?:public|protected|private) function ([^\(]+)


先程のPythonコードを、修正した正規表現に変更して確認してみます。

...中略...

# 正規表現パターンを指定
# pat = re.compile("(public|protected|private) function ([^\(]+)")
pat = re.compile("(?:public|protected|private) function ([^\(]+)")

# 条件に合致したものを全て取得
print(pat.findall(text))


# --------- 実行結果 ---------
['public_hoge', 'protected_hoge', 'private_hoge']

無事、関数名を取得することができました。

実際に自身で試してみたい方は、こちらの正規表現チェッカーで確かめてみてください。

まとめ

いかがだったでしょうか!

これを知らなかった時は取得後に毎回if文で条件分岐していましたが、知ったことで余計なものを取得せずにコード量も減ったのでタメになりました。

もっと正規表現を学びたい方は、オライリージャパンが出しているこちらの本がおすすめです。

この記事が誰かの役に立ちますように

正規表現カテゴリの最新記事