#!/usr/bin/perl
# https://perlmonks.org/?node_id=1224600
use strict;
use warnings;
use Data::Dump 'dd';
my $data = <<'END';
interface XYZ
given param1 -> child of "interface XYZ"
given param2 -> child of "interface XYZ"
given param2.1 -> child of "given param2"
given param2.1.1 -> child of "given param2.1"
given param2.1.2 -> child of "given param2.1"
given param2.2 -> child of "given param2"
given param3 -> child of "interface XYZ"
given param4 -> child of "interface XYZ"
interface SECOND
given param5 -> child of "interface SECOND"
END
my $struct = buildstruct($data);
dd $struct;
sub buildstruct
{
my $block = shift;
my @answers;
while( $block =~ /^ # make sure to start at beginning of a line (wit
+h m)
(\ *) # match leading spaces of header line
(.*) # match rest of line, save as head
\n # and match the newline
(
(?: # match all following lines with
\1 # same whitespace as head
\ + # plus at least one more space ( i.e. indented )
.*\n # contents to be looked at later
)* # as many as possible
) # save as rest
/gmx ) # global, multiline, and extra whitespace
{
my ($head, $rest) = ($2, $3);
$head =~ s/ ->.*//;
push @answers, $rest ? { $head => buildstruct($rest) } : $head;
}
\@answers;
}
I hope this helps :)
The regex matches each line, gets the indentation space string, then also matches all
following lines that are indented that much plus at least one more space.
|