ツリー全体を解析することを選択しますが、正規表現のみを使用すると問題を解決できます。
use strict; use warnings; use feature qw(say);
my $string = "((A:14,B:43):22,C:76,(D:54,(E:87,F:28):17):35)";
$string =~ s/^\(//;
$string =~ s/\)$//;
$string =~ s{
\G ((?&PRELEM)) : (\d+) (,|$)
(?(DEFINE)
(?<SUBLIST> [(] (?&ELEM)(?:,(?&ELEM))* [)] )
(?<ELEM> (?&PRELEM) : \d+ )
(?<PRELEM> (?:[A-Z]|(?&SUBLIST)) )
)
}{"$1:".($2+10).$3}gex;
say "($string)";
印刷し((A:14,B:43):32,C:86,(D:54,(E:87,F:28):17):45)
ます。
トップダウンの再帰的解析のための小さな文法を定義します。必要に応じて変更してください。最上位には、興味のないプレ要素があり、これを格納し$1
ます。これらは、単一の文字または括弧で囲まれたツリーにすることができます。a の後に:
は、インクリメントする数値が続き、 に格納され$2
ます。その後に、文字列の末尾またはカンマが続きます。最後の一致が残ったところから始めて、反復的に一致します (/g
オプションと\G
アサーションによって記号化されます)。追加は、置換文字列を作成するときに発生します (/e
オプションを使用しています)。