質問: rexp.sub(add_separator, text) return text ```
回答: 一番簡単なのは、括弧の数を数えるやり方だと思います。つまり、以下の方法です。 * 括弧のネストのレベルを数える変数を1つ用意し、文字列の最初から1文字ずつ読んでいって、開き括弧があればレベルを+1、閉じ括弧があればレベルを-1にしていきます。 * その途中で「レベルが0から1になったところ」から「レベルが1から0になったところ」までが一番外側の括弧に囲まれているところです。 * どこかでレベルがマイナスの値になったら、括弧の対応が上手く取れていません。エラーです。 あるいは適当なパーザーを書いてもいいですが、本質的には似たようなことをするような気がします。 どうしても正規表現で解決したいということであれば、再帰表現の入った正規表現であれば使えます。Pythonでは`re`の代わりに`regex`を使うと再帰を使えます。たとえば以下の正規表現が考えられます。 ``` (?「(?:[^「」]+|(?&rec))*」) ``` この(拡張)正規表現を説明すると以下の通りです。 * `(? ...)`: この中身を`rec`という名前で覚えておく。 * `(?:[^「」]+|(?&rec))`: 鍵括弧の無い文字列が続くか、rec自体にマッチする。 + `(?: ...)`はマッチを確認するがキャプチャしないグループを示しています(参考)。 + rec自体は "対応のとれた開き括弧から閉じ括弧までの文字列" を大体意味しているので、これで括弧の中に括弧があっても大丈夫になっています。 Takayukiさんの回答には(本質的には同じですが)よりコンパクトな正規表現が載っているのでこちらも参考になるかと思います。 また、正規表現を使った場合、もしかするとパフォーマンスに影響があるかもしれません。Pythonの正規表現エンジンの実装について私は詳しくないので、実際に試してみて影響があれば上に書いた単純な方法に変えた方が良いでしょう。 関連 * "Python: How to match nested parentheses with regex?" -- Stack Overflow + 特に、ovgolovinさんの回答が regex を使っています。 ちなみに「括弧の入れ子対応が上手くとれているか」を **純粋な** 正規表現でチェックすることはできません。 上手く対応がとれた括弧文字列たちの集合をダイク言語 (Dyck言語) と言うのですが、理論的に、これが正規言語でないことが知られているためです。 この点についてより詳しくは、Wikipediaの記事や、書籍『正規表現技術入門』などが参考になるのではないかと思います。 * ディック言語 / Dyck language -- Wikipedia * Regular language#The number of words in a regular language -- Wikipedia * 『正規表現技術入門』 -- amazon.co.jp