You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Wesley Peng <we...@magenta.de> on 2020/01/09 02:36:19 UTC

how to run regex calculation

Hello

Give the case I have a string,

$str = "2 3 6";

I want to match with:

true if $str =~ /(\d+)\s(\d+)\s($1*$2)/;

that's to say, the thrid column would be (firstCol * SecondCol).

How to write regex for this?

Thank you.

Re: how to run regex calculation

Posted by demerphq <de...@gmail.com>.
Sure you can. See joseph he's answer. 😀

Yves

On Mon, 13 Jan 2020, 05:06 Paul B. Henson, <he...@acm.org> wrote:

> On Thu, Jan 09, 2020 at 10:36:19AM +0800, Wesley Peng wrote:
>
> > $str = "2 3 6";
> >
> > I want to match with:
> >
> > true if $str =~ /(\d+)\s(\d+)\s($1*$2)/;
> >
> > that's to say, the thrid column would be (firstCol * SecondCol).
> >
> > How to write regex for this?
>
> I don't think you can do it directly in the regex. You'll need to do the
> math separately:
>
>         if ($str =~ /^(\d+)\s(\d+)\s(\d+)$/ && $3 == $1 * $2) {
>                 print "true\n"
>         }
>         else {
>                 print "false\n";
>         }
>

Re: how to run regex calculation

Posted by "Paul B. Henson" <he...@acm.org>.
On Thu, Jan 09, 2020 at 10:36:19AM +0800, Wesley Peng wrote:

> $str = "2 3 6";
> 
> I want to match with:
> 
> true if $str =~ /(\d+)\s(\d+)\s($1*$2)/;
> 
> that's to say, the thrid column would be (firstCol * SecondCol).
> 
> How to write regex for this?

I don't think you can do it directly in the regex. You'll need to do the
math separately:

	if ($str =~ /^(\d+)\s(\d+)\s(\d+)$/ && $3 == $1 * $2) {
		print "true\n"
	}
	else {
		print "false\n";
	}

Re: how to run regex calculation

Posted by demerphq <de...@gmail.com>.
On Thu, 9 Jan 2020 at 17:25, MIchael Capone <mc...@cablewholesale.com> wrote:
>
> It probably won't ever work.

Joseph He's solution works just fine:

perl -le'for my $str ("2 3 6", "1 1 1" ,"1 2 3","123 456 56088"){
print "($str)", $str =~ /(\d+)\s(\d+)\s(??{ $1 * $2 })/ ? " matched" :
" rejected"}'
(2 3 6) matched
(1 1 1) matched
(1 2 3) rejected
(123 456 56088) matched

(??{ ... }) is the recursive/deferred pattern,  it executes code and
then uses the final result as a new pattern that must match at the
current position in the string.

Yves

Yves

Re: how to run regex calculation

Posted by Alex Mestiashvili <am...@rsh2.donotuse.de>.
I am not subscribed to the list, so sending to the authors too.

This seem to work:

echo "2 3 6" |perl -Mstrict -pE 's{(\d+)\s(\d+)\s(\d+)}{my 
$r="false";$r="true" if $3 == eval"$1*$2";$r}e;'

perl -Mstrict -lE 'my $str = "2 3 7"; $str =~ s{(\d+)\s(\d+)\s(\d+)}{my 
$result="false";$result="true" if $3 == eval"$1*$2";$result}e;say $str'

The magic is the /e modifier.

Regards,
Alex

On 1/9/20 5:25 PM, MIchael Capone wrote:
> It probably won't ever work.  The problem is the * (star/asterisk) after 
> \1 is being interpreted in the context of regular expressions, ie, 
> "zero-or-more matches", and not as a multiplication operator.  In fact,
> 
> ~]$ perl -Mstrict -le 'my $str = "2 3 23"; print "true" if 
> $str=~/(\d+)\s(\d+)\s(\1*\2)/'
> 
> ...does indeed print "true"
> 
> It would probably make the most sense to not try to do this as a 
> one-liner (why do we perl programmers love to be cute like that?), and 
> simply break it up into two steps:
> 
> $str =~ s/(\d+)\s(\d+)\s(\d+)/;
> print "true" if ($1*$2 == $3);
> 
> - Michael
> 
> 
> 
> On 1/9/2020 12:39 AM, Wesley Peng wrote:
>> Hallo
>>
>> on 2020/1/9 16:35, demerphq wrote:
>>> $str=~/(\d+)\s(\d+)\s(\1*\2)/
>>>
>>> $1 refers to the capture buffers from the last completed match, \1
>>> inside of the pattern part of a regex refers to the capture buffer of
>>> the currently matching regex.
>>
>> This doesn't work too.
>>
>> perl -Mstrict -le 'my $str = "2 3 6"; print "true" if 
>> $str=~/(\d+)\s(\d+)\s(\1*\2)/'
>>
>> nothing printed.
>>
>>
>> Regards.

Re: how to run regex calculation

Posted by MIchael Capone <mc...@cablewholesale.com>.
It probably won't ever work.  The problem is the * (star/asterisk) after 
\1 is being interpreted in the context of regular expressions, ie, 
"zero-or-more matches", and not as a multiplication operator.  In fact,

~]$ perl -Mstrict -le 'my $str = "2 3 23"; print "true" if 
$str=~/(\d+)\s(\d+)\s(\1*\2)/'

...does indeed print "true"

It would probably make the most sense to not try to do this as a 
one-liner (why do we perl programmers love to be cute like that?), and 
simply break it up into two steps:

$str =~ s/(\d+)\s(\d+)\s(\d+)/;
print "true" if ($1*$2 == $3);

- Michael



On 1/9/2020 12:39 AM, Wesley Peng wrote:
> Hallo
>
> on 2020/1/9 16:35, demerphq wrote:
>> $str=~/(\d+)\s(\d+)\s(\1*\2)/
>>
>> $1 refers to the capture buffers from the last completed match, \1
>> inside of the pattern part of a regex refers to the capture buffer of
>> the currently matching regex.
>
> This doesn't work too.
>
> perl -Mstrict -le 'my $str = "2 3 6"; print "true" if 
> $str=~/(\d+)\s(\d+)\s(\1*\2)/'
>
> nothing printed.
>
>
> Regards.

Re: how to run regex calculation

Posted by demerphq <de...@gmail.com>.
Oh. Heh. I misunderstood the intent. I thought you wanted to match a
sequence of digits followed by a space followed by more digits followed by
a space followed by the first set of digits repeated 0 or more times
followed by the second set of digits. If you want multiplication then
Joseph He's original answer was correct.

Yves

On Thu, 9 Jan 2020, 09:40 Wesley Peng, <we...@magenta.de> wrote:

> Hallo
>
> on 2020/1/9 16:35, demerphq wrote:
> > $str=~/(\d+)\s(\d+)\s(\1*\2)/
> >
> > $1 refers to the capture buffers from the last completed match, \1
> > inside of the pattern part of a regex refers to the capture buffer of
> > the currently matching regex.
>
> This doesn't work too.
>
> perl -Mstrict -le 'my $str = "2 3 6"; print "true" if
> $str=~/(\d+)\s(\d+)\s(\1*\2)/'
>
> nothing printed.
>
>
> Regards.
>

Re: how to run regex calculation

Posted by Wesley Peng <we...@magenta.de>.
Hallo

on 2020/1/9 16:35, demerphq wrote:
> $str=~/(\d+)\s(\d+)\s(\1*\2)/
> 
> $1 refers to the capture buffers from the last completed match, \1
> inside of the pattern part of a regex refers to the capture buffer of
> the currently matching regex.

This doesn't work too.

perl -Mstrict -le 'my $str = "2 3 6"; print "true" if 
$str=~/(\d+)\s(\d+)\s(\1*\2)/'

nothing printed.


Regards.

Re: how to run regex calculation

Posted by demerphq <de...@gmail.com>.
This isnt really the forum for random perl help, i suggest Perlmonks instead.

$str=~/(\d+)\s(\d+)\s(\1*\2)/

$1 refers to the capture buffers from the last completed match, \1
inside of the pattern part of a regex refers to the capture buffer of
the currently matching regex.

Yves

On Thu, 9 Jan 2020 at 03:36, Wesley Peng <we...@magenta.de> wrote:
>
> Hello
>
> Give the case I have a string,
>
> $str = "2 3 6";
>
> I want to match with:
>
> true if $str =~ /(\d+)\s(\d+)\s($1*$2)/;
>
> that's to say, the thrid column would be (firstCol * SecondCol).
>
> How to write regex for this?
>
> Thank you.



-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

Re: how to run regex calculation

Posted by demerphq <de...@gmail.com>.
My apologies you were right. I misunderstood the question. Yves

On Thu, 9 Jan 2020, 09:39 demerphq, <de...@gmail.com> wrote:

> On Thu, 9 Jan 2020 at 05:49, Joseph He <jo...@gmail.com> wrote:
> >
> > I think $str =~ /(\d+)\s(\d+)\s(??{$1*$2})/   should do it
> > My Perl version is  v5.26.1
>
> I think you mean (??{ "$1*$2"}) which might work, but it will be error
> prone, (??{"(?$1)*$2") would be better, but both will be slow, as each
> time a new pattern willbe compiled.
>
> /(\d+)\s(\d+)\s(\1*\2)/
>
> just works, and does not recompile the pattern over and over. Look for
> "back references" in perlre.
>
> Yves
>

Re: how to run regex calculation

Posted by demerphq <de...@gmail.com>.
On Thu, 9 Jan 2020 at 05:49, Joseph He <jo...@gmail.com> wrote:
>
> I think $str =~ /(\d+)\s(\d+)\s(??{$1*$2})/   should do it
> My Perl version is  v5.26.1

I think you mean (??{ "$1*$2"}) which might work, but it will be error
prone, (??{"(?$1)*$2") would be better, but both will be slow, as each
time a new pattern willbe compiled.

/(\d+)\s(\d+)\s(\1*\2)/

just works, and does not recompile the pattern over and over. Look for
"back references" in perlre.

Yves

Re: how to run regex calculation

Posted by Jan Pazdziora <jp...@adelton.com>.
On Thu, Jan 09, 2020 at 05:21:38PM +0800, Wesley Peng wrote:
> what does (??{$1*$2}) means?

Check the perlre(1) man page for explanation of "(??{ code })".

As already mentioned, other venues like Perlmonks might serve better
for the generic Perl questions.

-- 
Jan Pazdziora

Re: how to run regex calculation

Posted by Wesley Peng <we...@magenta.de>.
what does (??{$1*$2}) means?

Thanks.

on 2020/1/9 12:49, Joseph He wrote:
> I think $str =~ /(\d+)\s(\d+)\s(??{$1*$2})/   should do it
> My Perl version is  v5.26.1
> 

Re: how to run regex calculation

Posted by Joseph He <jo...@gmail.com>.
I think $str =~ /(\d+)\s(\d+)\s(??{$1*$2})/   should do it
My Perl version is  v5.26.1

Joseph

On Wed, Jan 8, 2020 at 8:36 PM Wesley Peng <we...@magenta.de> wrote:

> Hello
>
> Give the case I have a string,
>
> $str = "2 3 6";
>
> I want to match with:
>
> true if $str =~ /(\d+)\s(\d+)\s($1*$2)/;
>
> that's to say, the thrid column would be (firstCol * SecondCol).
>
> How to write regex for this?
>
> Thank you.
>