regex showdown

Discussion in 'Perl Misc' started by si, Apr 20, 2005.

  1. si

    si Guest

    hi, i have a regex question for the gurus here

    str = "aa (b c d) ee ff=1.7e-006 gg=4.1 hh=1 ii=on"

    notes:
    - the string between the parenthesis can be any length,
    eg:( b c d b1 c1 d1 b2 c2 etc.... )
    - there can be any number of name=value pairs at the end of the
    expression
    eg: ff=1.7e-006 gg=4.1 hh=1 ii=on jj=2.5 kk=connected etc


    what would be regex that would return the below?

    $name = 'aa'

    @friends = ('b', 'c', 'd')

    $alias = 'ee'

    %pairs = ( 'ff', 1.7e-006,
    'gg', 4.1,
    'hh', 1, etc .. )


    thx thx thx!
     
    si, Apr 20, 2005
    #1
    1. Advertising

  2. si

    phaylon Guest

    si wrote:

    > what would be regex that would return the below?


    What have you tried? I'm always interested in getting better, but that
    doesn't mean that I'm gonna do other people's jobs.

    --
    http://www.dunkelheit.at/

    »Better to reign in hell than to serve in heaven«
    -- John Milton, »Paradise Lost«
     
    phaylon, Apr 20, 2005
    #2
    1. Advertising

  3. si wrote:
    > hi, i have a regex question for the gurus here
    >
    > str = "aa (b c d) ee ff=1.7e-006 gg=4.1 hh=1 ii=on"
    >
    > notes:
    > - the string between the parenthesis can be any length,
    > eg:( b c d b1 c1 d1 b2 c2 etc.... )
    > - there can be any number of name=value pairs at the end of the
    > expression
    > eg: ff=1.7e-006 gg=4.1 hh=1 ii=on jj=2.5 kk=connected etc
    >
    >
    > what would be regex that would return the below?
    >
    > $name = 'aa'
    >
    > @friends = ('b', 'c', 'd')
    >
    > $alias = 'ee'
    >
    > %pairs = ( 'ff', 1.7e-006,
    > 'gg', 4.1,
    > 'hh', 1, etc .. )
    >


    Break the problem into chunks: you might be able to do most of it in one
    go, but it would be nearly impossible to maintain.

    Hint: your test string has four distinct parts. Take it from there.

    Other here posters could easily provide you with a regex to do this
    first step (which is the meat of the problem), but as has been pointed
    out, you don't appear to have tried anything yet and this place is
    supposed to be for asking advice, not for asking others to do your work.


    Mark
     
    Mark Clements, Apr 20, 2005
    #3
  4. si

    si Guest

    sorry guys, i have tried a few things but they didn't work out so i
    didn't post them... here's my latest attempt

    i'm kind of a newbie with regexp so don't laugh


    /^(?<name>\w+)(*(?<pins>\w+)\s*)*(?<masterNm>\w)\s*(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/

    $name = $1;
    @friends = $2;
    $alias = $3
    %pairs ....

    i was trying to avoid a while loop to populate @friends and %pairs but
    i couldn't figure this out from my Friedl book

    just trying to get a handle with this stuff...

    thx
     
    si, Apr 20, 2005
    #4
  5. si

    si Guest

    sorry that should have read

    /^(?\w+)(*(?\w+)\s­*)*(?\w)\s*(?\w­+)\s*=\s*(?\w+)/

    thx
     
    si, Apr 20, 2005
    #5
  6. si wrote:
    > sorry guys, i have tried a few things but they didn't work out so i
    > didn't post them... here's my latest attempt
    >
    > i'm kind of a newbie with regexp so don't laugh
    >
    >
    > /^(?<name>\w+)(*(?<pins>\w+)\s*)*(?<masterNm>\w)\s*(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
    >
    > $name = $1;
    > @friends = $2;
    > $alias = $3
    > %pairs ....
    >
    > i was trying to avoid a while loop to populate @friends and %pairs but
    > i couldn't figure this out from my Friedl book
    >
    > just trying to get a handle with this stuff...
    >
    > thx
    >


    > sorry that should have read


    > /^(?\w+)(*(?\w+)\s­*)*(?\w)\s*(?\w­+)\s*=\s*(?\w+)/


    OK - you are misunderstanding what ? and * do, and when () need to be
    escaped (and when they don't). You need to read man perlre carefully.
    Also have a look at man re - there are debug options that can be turned
    on for regular expressions that may help you.

    /(\w+)\s+\(((?:\w\s?)*)\)\s+(\w+)\s(.*)/);

    *seems* to work for me. Make sure you understand what the regex is doing.

    You can then use split and map to populate @friends and %pairs. Look at

    perldoc -f split
    perldoc -f map


    regards,

    Mark
     
    Mark Clements, Apr 20, 2005
    #6
  7. si

    Steven Kuo Guest

    On 20 Apr 2005, si wrote:

    > sorry guys, i have tried a few things but they didn't work out so i
    > didn't post them... here's my latest attempt
    >
    > i'm kind of a newbie with regexp so don't laugh
    >
    >
    > /^(?<name>\w+)(*(?<pins>\w+)\s*)*(?<masterNm>\w)\s*(?<lhs>\w+)\s*=\s*(?<rhs>\w+)/
    >
    > $name = $1;
    > @friends = $2;
    > $alias = $3
    > %pairs ....
    >
    > i was trying to avoid a while loop to populate @friends and %pairs but
    > i couldn't figure this out from my Friedl book
    >
    > just trying to get a handle with this stuff...





    Assuming you can reliably use space, the equal sign, and parentheses
    as delimiters, you can try:

    use Data::Dumper;

    $_ = 'aa (b c d) ee ff=1.7e-006 gg=4.1 hh=1 ii=on';
    my $count_hash_elements = 0;
    @_ = $_ =~ /([^ ()=]+)(?==(?{++$count_hash_elements}))?/g;
    my ($alias, %hash) = splice(@_, -1 - 2 * $count_hash_elements);
    my ($name, @friends) = @_;

    print <<"__QED__";
    NAME => $name
    FRIENDS => @{[ Dumper \@friends]}
    ALIAS => $alias
    HASH => @{[ Dumper \%hash ]}
    __QED__


    What's wrong with using a while loop? If well written, it's much
    easier to read and understand than what I've written. Take,
    for example, the code here:

    http://www.stonehenge.com/merlyn/UnixReview/col55.html

    courtesy of Randal.

    --
    Hope this helps,
    Steven
     
    Steven Kuo, Apr 20, 2005
    #7
  8. si <> wrote:

    > str = "aa (b c d) ee ff=1.7e-006 gg=4.1 hh=1 ii=on"



    > what would be regex that would return the below?
    >
    > $name = 'aa'
    >
    > @friends = ('b', 'c', 'd')
    >
    > $alias = 'ee'
    >
    > %pairs = ( 'ff', 1.7e-006,
    > 'gg', 4.1,
    > 'hh', 1, etc .. )



    if ($str =~ s/(\S+)\s+\(([^)]+)\)\s+(\S+)\s+// ) {
    $name = $1;
    $alias = $3;
    @friends = split /\s+/, $2;
    %pairs = split /[ =]+/, $str;
    }


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, Apr 20, 2005
    #8
  9. * Steven Kuo schrieb:
    > On 20 Apr 2005, si wrote:
    >>
    >> i was trying to avoid a while loop to populate @friends and %pairs but
    >> i couldn't figure this out from my Friedl book

    >
    > Assuming you can reliably use space, the equal sign, and parentheses
    > as delimiters, you can try:
    >
    > use Data::Dumper;
    >
    > $_ = 'aa (b c d) ee ff=1.7e-006 gg=4.1 hh=1 ii=on';
    > my $count_hash_elements = 0;
    > @_ = $_ =~ /([^ ()=]+)(?==(?{++$count_hash_elements}))?/g;
    > my ($alias, %hash) = splice(@_, -1 - 2 * $count_hash_elements);
    > my ($name, @friends) = @_;
    >
    > print <<"__QED__";
    > NAME => $name
    > FRIENDS => @{[ Dumper \@friends]}
    > ALIAS => $alias
    > HASH => @{[ Dumper \%hash ]}
    > __QED__
    >
    >
    > What's wrong with using a while loop? If well written, it's much
    > easier to read and understand than what I've written.


    The idea behind your code looks good. But, why counting the equal signs
    inside your regex and why splitting to @_. I'd write instead:


    $_ = 'aa (b c d) ee ff=1.7e-006 gg=4.1 hh=1 ii=on';

    my( $name, @friends ) = split /[ ()=]+/;
    my( $alias, %pairs ) = splice @friends, -1 - 2 * tr/=//;


    That's all. Splitting is done by split(), counting by tr/// and splice()
    is asked to isolate the hash %pairs. I don't think, that avoiding a
    while loop must be harder to read (btw, which loop at all? I haven't
    seen one in this thread yet). Sure, one has to know what the used
    functions will do, but therefor the docs are written.

    regards,
    fabian
     
    Fabian Pilkowski, Apr 21, 2005
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?SmViQnVzaGVsbA==?=

    Is ASP Validator Regex Engine Same As VS2003 Find Regex Engine?

    =?Utf-8?B?SmViQnVzaGVsbA==?=, Oct 22, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    736
    =?Utf-8?B?SmViQnVzaGVsbA==?=
    Oct 22, 2005
  2. Rick Venter

    perl regex to java regex

    Rick Venter, Oct 29, 2003, in forum: Java
    Replies:
    5
    Views:
    1,666
    Ant...
    Nov 6, 2003
  3. Replies:
    2
    Views:
    619
  4. Xah Lee
    Replies:
    1
    Views:
    960
    Ilias Lazaridis
    Sep 22, 2006
  5. Replies:
    3
    Views:
    809
    Reedick, Andrew
    Jul 1, 2008
Loading...

Share This Page