Первоначально я думал использовать именованные захваты и получать значения из %-
:
my $pattern = qr/
\(
"Data"\s+
\(Int\s+"A"\s+(?<A>[0-9]+)\)
(?:
\(Int\s+"B"\s+(?<B>[0-9]+)\)
\(Int\s+"C"\s+(?<C>[0-9]+)\)
)+
\(Int\s+"D"\s+(?<D>[0-9]+)\)
\(Int\s+"E"\s+(?<E>[0-9]+)\)
\)
/x;
К сожалению, группировка (?:...)
не вызывает захват нескольких значений для B и C. Я подозреваю, что это ошибка. Выполнение этого в явном виде фиксирует все значения, но вам нужно знать максимальное количество экземпляров заранее.
my $pattern = qr/
\(
"Data"\s+
\(Int\s+"A"\s+(?<A>[0-9]+)\)
\(Int\s+"B"\s+(?<B>[0-9]+)\)
\(Int\s+"C"\s+(?<C>[0-9]+)\)
(?:
\(Int\s+"B"\s+(?<B>[0-9]+)\)
\(Int\s+"C"\s+(?<C>[0-9]+)\)
)?
(?:
\(Int\s+"B"\s+(?<B>[0-9]+)\)
\(Int\s+"C"\s+(?<C>[0-9]+)\)
)?
# repeat (?:...) N times
\(Int\s+"D"\s+(?<D>[0-9]+)\)
\(Int\s+"E"\s+(?<E>[0-9]+)\)
\)
/x;
Самый простой подход - использовать m//g
. Вы можете захватить пары имя / значение, как предлагает Беано, или использовать несколько шаблонов для захвата каждого значения:
my @b = m/Int "B" ([0-9]+)/g;
my @c = m/Int "C" ([0-9]+)/g;
# etc.