Regular Expression Question

J

jonasforssell

Hello,


I have a file like this:

2 45 3
3 44 2 65

In other words, the first number states how many follwing numbers
there will be.

^([0-9]) ([0-9]){$1}$

The above regexp does not seem to work for parsing this. I guess the
$1 parameter is not accepted.
Any ideas of an alternative?

Thanks
/Jonas
 
B

Brian McCauley

Subject: Regular Expression Question

[ snip: question about using a backreference as a repeat count in
regex ]

Please put the subject of your post in the Subject of your post.

If in doubt try this simple test. Imagine you had done a search before
you posted. Then imagine that your subject line came up in the list of
hits. Would you have been able to guess with any degree of certainly
that it was the same question? If the answer is no then your subject
line is not good enough.

Remember: Just because you come here to get help not give it you
should not have the mindset that you are only here to take and have no
moral duty to give anything back to the community.

For example when poncenby asked this question on 6th Oct 2006 his
subject was "backreference oddity"[1]. Still not good but at least it
mentions that this is a question about backreferences.

A good subject would have been "Using a backreference as a repeat
count in regex".

[1] Looking up this thread to see the answer is left as an exercise
for the reader.
 
M

Martijn Lievaart

Hello,


I have a file like this:

2 45 3
3 44 2 65

In other words, the first number states how many follwing numbers there
will be.

^([0-9]) ([0-9]){$1}$

The above regexp does not seem to work for parsing this. I guess the $1
parameter is not accepted.
Any ideas of an alternative?

I think $1 is substituted before matching against the regexp, so you get
the value that was in $1 before the match. I guess something like the
following (untested!) should work.

if (/^(\d+)/) {
if (/(\d+) (?:(\d+) ?){$1}$/) {
# we have a match
}
}

HTH,
M4
 
M

Mirco Wahab

Hello,


I have a file like this:

2 45 3
3 44 2 65

In other words, the first number states how many follwing numbers
there will be.

^([0-9]) ([0-9]){$1}$

The above regexp does not seem to work for parsing this. I guess the
$1 parameter is not accepted.
Any ideas of an alternative?

You could use dynamic quantifier. I'm not sure,
one can put \1 directly into a quantifier
(maybe it works sometimes).

This works - dynamic quantifier by (??{ ... })

...

print grep /^ # lock to start of line
(\d+)\s+ # extract quantifier + space
(??{ "(\\d+\\s+){$1}" }) # construct the (\d+\s+){N} thing
$ # lock to end of line
/x, <DATA>;

...

__DATA__
2 45 3
3 44 2 65
5 43 4 43 4444
1 43 4 43 4444
3 44 2 65

Regards

M.
 
J

John W. Krahn

I have a file like this:

2 45 3
3 44 2 65

In other words, the first number states how many follwing numbers
there will be.

^([0-9]) ([0-9]){$1}$

The above regexp does not seem to work for parsing this. I guess the
$1 parameter is not accepted.
Any ideas of an alternative?

while ( <FILE> ) {
my ( $count, @data ) = /\d+/g;
if ( $count == @data ) {
print "Yes! we have valid data.\n";
}
else {
warn "Error: expected $count elements but received " . @data . "
instead.\n";
}
}



John
 
M

Mumia W.

Hello,


I have a file like this:

2 45 3
3 44 2 65

In other words, the first number states how many follwing numbers
there will be.

^([0-9]) ([0-9]){$1}$

The above regexp does not seem to work for parsing this. I guess the
$1 parameter is not accepted.
Any ideas of an alternative?

Thanks
/Jonas

The task is complicated by the fact that $1 is not valid until the
regular expression that sets it is finished. Here's one way to do it:

my $data = q{ 2 45 3 5 6 7 8 };
# 5 6 7 and 8 should be ignored.

my @nums = do {
$data =~ /^ *(\d) ([\d ]+)/
&& ($2 =~ /((?:\d+ +){$1})/)
&& ($1 =~ /\d+/g)
};
 
M

Mirco Wahab

John said:
while ( <FILE> ) {
my ( $count, @data ) = /\d+/g;
if ( $count == @data ) {
print "Yes! we have valid data.\n";
}
else {
warn "Error: expected $count elements but received " . @data . " instead.\n";
}
}

Good idea!

in Perl, your approach would then look like

my @data = grep $_->[0] == @$_-1, map [split], <FILE>;

or something, I guess ;-)

Regards

M.
 
C

comp.llang.perl.moderated

I have a file like this:
2 45 3
3 44 2 65
In other words, the first number states how many follwing numbers
there will be.
^([0-9]) ([0-9]){$1}$
The above regexp does not seem to work for parsing this. I guess the
$1 parameter is not accepted.
Any ideas of an alternative?

while ( <FILE> ) {
my ( $count, @data ) = /\d+/g;
if ( $count == @data ) {
print "Yes! we have valid data.\n";
}
else {
warn "Error: expected $count elements but received " . @data . "
instead.\n";
}
}

Or, if backref's weren't required:

my( $tot, $cnt );
print "yes..." if $tot = ($cnt,()) = /\d+/g and $tot == $cnt+1;
 

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,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top