Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

using Text::Balanced

by slugger415 (Monk)
on Jan 30, 2014 at 23:53 UTC ( [id://1072751]=perlquestion: print w/replies, xml ) Need Help??

slugger415 has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, I'm having a junior moment, not understanding how to use Text::Balanced on a fairly simple set of text. I have a string containing nested square brackets I'd like to parse out into its useful elements. Here's my code:

use Text::Balanced; my $str = " ['listliteral',['ListLiteral',['../classSPL_1_1Operator_1 +_1Instance_1_1ExpressionTree_1_1ListLiteral.html',1,'SPL::Operator::I +nstance::ExpressionTree']]]"; @matches = Text::Balanced::extract_bracketed( $str, '[]' ); foreach (@matches) { print "$_\n"; }

This yields:

['listliteral',['ListLiteral','../classSPL_1_1Operator_1_1Instance_1_1Expression nTree_1_1ListLiteral.html',1,'SPL::Operator::Instance::ExpressionTree']]

What I'd like is for each [..] to be its own value in @matches. How do I do that?

And yes I did try reading the doc, but it's way over my junior head :-( ... thanks

Replies are listed 'Best First'.
Re: using Text::Balanced
by tobyink (Canon) on Jan 31, 2014 at 00:18 UTC

    That ain't what Text::Balanced does.

    Text::Balanced::extract_bracketed( $str, '[]' );

    ... will extract the first (and only the first) [...] delimited string, allowing balanced pairs of square brackets within it. It doesn't attempt to then do any parsing within that string. It will also return the remainder of the input string, so you can parse that remainder to, for example, find the next [...] delimited string.

    If you need deep parsing, then you need to write a recursive function. Something like this:

    use strict; use warnings; use Text::Balanced qw(extract_quotelike); use Data::Dumper; sub parse_str { my $str = shift; $str =~ s/\A\s*//; # list-like if ($str =~ /\A\s*\[/) { # eat initial [ $str =~ s/\A\s*\[\s*//; my @arr; while ($str !~ /\A\s*\]/) { my ($term, $remainder) = parse_str($str); push @arr, $term; if ($remainder =~ /\A\s*[,\]]/) { $str = $remainder; $str =~ s/\A\s*,\s*//; } else { die "Expected comma; got <<<$remainder>>>"; } } # eat trailing ] $str =~ s/\A\s*\]\s*//; return \@arr, $str; } # quote-like elsif ($str =~ /\A['"]/) { my ($term, $remainder) = extract_quotelike($str); $term =~ s/\A['"]//; $term =~ s/['"]\z//; return ($term, $remainder); } # number-like or bareword-like elsif ($str =~ /\A([\w\.]+)/) { my $term = $1; return ($term, substr($str, length($term))); } die "Expected something else; got <<<$str>>>"; } print Dumper parse_str <<DATA; [ 'listliteral', [ 'ListLiteral', [ '../classSPL_1_1Operator_1_1Instance_1_1ExpressionTree_1_1 +ListLiteral.html', 1, 'SPL::Operator::Instance::ExpressionTree' ] ] ] DATA
    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name
      Good, thank you.
Re: using Text::Balanced (JSON)
by Anonymous Monk on Jan 31, 2014 at 00:15 UTC

    How do I do that?

    Recognize that what you have is JSON and use a JSON module :)

    #!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd pp /; use JSON qw/ to_json from_json /; my $str = q{["listliteral",["ListLiteral",["../classSPL_1_1Operator_1_ +1Instance_1_1ExpressionTree_1_1ListLiteral.html",1,"SPL::Operator::In +stance::ExpressionTree"]]]}; dd( from_json( $str ) ); __END__ [ "listliteral", [ "ListLiteral", [ "../classSPL_1_1Operator_1_1Instance_1_1ExpressionTree_1_1ListLi +teral.html", 1, "SPL::Operator::Instance::ExpressionTree", ], ], ]

    Oh, but you say I switched the single quotes for the double quotes ... :P

    Well, what you do have is also perl, so use Safe

    #!/usr/bin/perl -- use strict; use warnings; use Data::Dump qw/ dd pp /; use Safe; my $str = q{["listliteral",["ListLiteral",["../classSPL_1_1Operator_1_ +1Instance_1_1ExpressionTree_1_1ListLiteral.html",1,"SPL::Operator::In +stance::ExpressionTree"]]]}; dd( Safe->new->reval( $str ) ); __END__ [ "listliteral", [ "ListLiteral", [ "../classSPL_1_1Operator_1_1Instance_1_1ExpressionTree_1_1ListLi +teral.html", 1, "SPL::Operator::Instance::ExpressionTree", ], ], ]
      very nice, thank you!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1072751]
Approved by boftx
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (6)
As of 2024-04-18 11:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found