Problem splitting lines from file input

M

Mothra

I'm trying to parse a log file using ';' as a newline and then wherever
I find items inside '(..)', indenting those lines thus:


foo;bar(foo;bar(foobar);foo)foobar

becomes

foo
bar(
foo
bar(
foobar
)
foo
)
foobar

What I've got so far is below - the problem is that when there are
nested sets of parentheses, I can't increase the indents accordingly.
Also, I can't work out how to get the closing ')' on a line by itself.

I'm in a bit of a pickle - can anyone help?

What I've got so far follows:


#!/usr/bin/perl -w
use strict;
$|=0;

my @in = <>;
my $tbchr = "\t";
my $tbcnt = 0;

for(@in){
my @ln=split(';', $_);
my $i;
for ($i=0; $i<@ln; $i++){
chomp($ln[$i]);
my @subln;
if ( $ln[$i] =~ /\([^)]/ ) {
@subln = split('\(',$ln[$i]);
my $k;for($k=0;$k<@subln;$k++){ $subln[$k] .=
'(' }
} elsif ( $ln[$i] =~ /[^(]\)/ ) {
@subln = split('\)',$ln[$i]);
my $k;for($k=0;$k<@subln;$k++){ $subln[$k] .=
')' }
} else {
@subln = $ln[$i];
}


for(@subln){
my $j;
for($j=0; $j<$tbcnt; $j++){ print $tbchr }
print "$_\n";
$tbcnt++ if /\(/;
$tbcnt-- if /\)/;
}

}
}
 
A

Arndt Jonasson

Mothra said:
I'm trying to parse a log file using ';' as a newline and then wherever
I find items inside '(..)', indenting those lines thus:


foo;bar(foo;bar(foobar);foo)foobar

becomes

foo
bar(
foo
bar(
foobar
)
foo
)
foobar

What I've got so far is below - the problem is that when there are
nested sets of parentheses, I can't increase the indents accordingly.
Also, I can't work out how to get the closing ')' on a line by itself.

I found your code far too complicated to try to understand, so I wrote
this version instead (not meant to be particularly clever or neat - I'm
sure there are things to improve in it):

#! /usr/local/bin/perl

use strict;
use warnings;

my $level = 0;

sub newline {
print "\n", " " x (4*$level);
}

while (<>) {
for (split //) {
if ($_ eq ";") {
newline();
} elsif ($_ eq "(") {
print $_;
$level++;
newline();
} elsif ($_ eq ")") {
$level--;
newline();
print $_;
newline();
} else {
print $_;
}
}
}

print "\n";

I didn't address the requirement of printing ')' on their own lines, but
you can probably modify my program to do so.

I think there's an ambiguity in your input/output data: you have ");"
in one place and just ")" in another, but in the output, both ')'
characters are followed by precisely one newline.
 
M

Mothra

I found your code far too complicated to try to understand, so I wrote
this version instead (not meant to be particularly clever or neat - I'm
sure there are things to improve in it):

My original script simply split lines on ';'. I was then asked to modify
it to do the stuff with parentheses, hence it got a bit ugly! :)

I didn't address the requirement of printing ')' on their own lines, but
you can probably modify my program to do so.
Thanks - the structure of your script is a lot better than mine.
I think there's an ambiguity in your input/output data: you have ");"
in one place and just ")" in another, but in the output, both ')'
characters are followed by precisely one newline.
Sorry about that - the real data I'm parsing is customer names, adresses,
bank details etc., so I couldn't post that.
 
A

Anno Siegel

Mothra said:
I'm trying to parse a log file using ';' as a newline and then wherever
I find items inside '(..)', indenting those lines thus:

Sounds like a job for Text::Balanced.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top