Pythonの正規表現では、ネストしたグループを扱うことは困難で、不可能な場合もあります。しかし、一部の正規表現エンジンでは、限定的な「ネスト」構造をサポートしています。
ネストしたグループを扱う一つのアプローチは、パーシング文法を使用することです。以下に、Eric Roseのparsimoniousライブラリを使用した3ステップの例を示します。
import itertools as it
import parsimonious as pars
source = "\"\"\"\\ /TT0 1 Tf 0.002 Tc -0.002 Tw 11.04 0 0 11.04 221.16 707.04 Tm [(\\()-2(Y)7(o)7(u )-3(g)7(o)-2(t )4(i)-3(t)(\\))]TJ EMC\"\"\"
rules = r\"\"\"
root = line line message end
line = ANY NEWLINE
message = _ TEXT (_ TEXT*)* NEWLINE
end = \"EMC\" NEWLINE*
TEXT = ~r\"[a-zA-Z ]+\"
NEWLINE = ~r\"\\n\"
ANY = ~r\"[^\\n\\r]*\"
_ = meaninglessness*
meaninglessness = ~r\"(TJ)*[^a-zA-Z\\n\\r]*\"
\"\"\"
grammar = pars.grammar.Grammar(rules)
tree = grammar.parse(source)
class Translator(pars.NodeVisitor):
def visit_root(self, node, children): return children
def visit_line(self, node, children): return node.text
def visit_message(self, node, children): _, s, remaining, nl = children return (s + \"\".join(it.chain.from_iterable(i[1] for i in remaining)) + nl)
def visit_end(self, node, children): return node.text
def visit_meaninglessness(self, node, children): return children
def visit__(self, node, children): return children[0]
def visit_(self, node, children): return children
def visit_TEXT(self, node, children): return node.text
def visit_NEWLINE(self, node, children): return node.text
def visit_ANY(self, node, children):
\"\"\"
このように、Pythonの正規表現を使用してネストしたグループを扱うことは困難であるため、パーシングライブラリを使用することが推奨されます。