regex showdown

S

si

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!
 
P

phaylon

si said:
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.
 
M

Mark Clements

si said:
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
 
S

si

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
 
M

Mark Clements

si said:
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
 
S

Steven Kuo

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.
 
T

Tad McClellan

si said:
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;
}
 
F

Fabian Pilkowski

* Steven Kuo said:
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
 

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

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top