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

I want to get the string between . and first ( put it in $pin and I want to extract the stuff inside outer () put it in $sig my code is stripping the ending )s could someone correct my code, it's clumsy and stupid :
my $sp = ".A(~(B & C & ( D | (E & F) ))),"; ## $pin = string between . and ( if ( $sp =~ /\.(.*?)\(/ ) { $pin = $1; } if ( $sp =~ /\((.*?)\)/ ) { $sig = $1; }
Thanks in advance.

Replies are listed 'Best First'.
Re: Parsing Strings (Verilog)
by toolic (Bishop) on Mar 12, 2016 at 02:50 UTC
Re: Parsing Strings
by Athanasius (Archbishop) on Mar 12, 2016 at 02:58 UTC

    Hello doofus,

    To capture the literal parentheses, put them inside the capturing parentheses. But you want the outermost parentheses, so change to a greedy quantifier. And if you know that your input string is such that the text captured in $pin will always precede the text captured in $sig, you can combine the two regular expressions into one:

    if ($sp =~ m{ \. ( [^(]* ) ( \( .* \) ) }x) { print "pin = $1\n"; print "sig = $2\n"; }

    But note that this does not guarantee that the outer parentheses are matched. For that, you will need to use the techniques described in perlfaq6, “Can I use Perl regular expressions to match balanced text?”

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Re: Parsing Strings
by AnomalousMonk (Archbishop) on Mar 12, 2016 at 03:11 UTC
Re: Parsing Strings
by ww (Archbishop) on Mar 12, 2016 at 02:59 UTC

    Not stupid -- except (some would argue) for the failure to use strict, warnings and some prints -- and clumsy (IMO) only in your indentation.

    That said, the following seems to be what you want. More commentary follows:

    #!/usr/bin/perl -w use strict; use 5.018; # 1157516 my $sp = ".A(~(B & C & ( D | (E & F) ))),"; # $pin = string between . and ( if ( $sp =~ /\.(.*?)\(/ ) { my $pin = $1; say "|-- $pin --|\n"; } my $sig; # if ( $sp =~ /\((.*?)\)/ ) { if ( $sp =~ /\( (.*?\){2}) .*/x ) { $sig = $1; } say "\t|-> $sig <-|";

    The /x modifer isn't necessary; it merely makes it easier to read the second regex; the use of the quantifier lets the regex capture all but the last ")" (the space between the one which trails "F" before the 3 parens leaves the one after the "F" out of consideration).

      Thank you all for the suggestions. Hi Ww, Adding an extra (), then ending ) is missing. Any ideas?
      Test 1 : sp = .A(~(B & C & ( D | (E & F) ))), pin = A sig = ~(B & C & ( D | (E & F) )) Test 2 : sp = .A(~((B & C & ( D | (E & F) )))), pin = A sig = ~((B & C & ( D | (E & F) ))

        Now you've asked a question that begs for a reply of "lazy question." But, I suggest you direct your attention to the regex docs, with special attention to quantifiers (of the sort I illustrated.

        At your command prompt: perldoc perlre<c>, <c>perldoc perlrequick and perldoc perlretut and similarly for other questions about perl (perldoc perldoc is a good place to start).


        Questions containing the words "doesn't work" (or their moral equivalent) will usually get a downvote from me unless accompanied by:
        1. code
        2. verbatim error and/or warning messages
        3. a coherent explanation of what "doesn't work actually means.