conditional regular expressions
conditional regular expressions
am 13.08.2007 14:37:59 von Morfys
hi,
I was having trouble understanding how regular conditional expressions
work. In particular, in this piece of code:
$str = "ttt, 2";
if(($result) = $str =~ /\w\w\w(?(?=, )(\d))/){
print "$result\n";
}
I don't understand why there is empty output versus "2".
The desired effect is that $result contain the digit following ", " if
it exists in the string.
I've tried almost every variation of the regular expression but I'm
missing something. Thanks in advance for any help.
Re: conditional regular expressions
am 13.08.2007 14:54:50 von Mirco Wahab
Morfys wrote:
> $str = "ttt, 2";
> if(($result) = $str =~ /\w\w\w(?(?=, )(\d))/){
> print "$result\n";
> }
> I don't understand why there is empty output versus "2".
> The desired effect is that $result contain the digit following ", " if
> it exists in the string.
The regular expression is stepped through from
left to right. Therefore there is an implicit
"the more right pattern matches only if the more
left pattern already matched", which leads to the
trivial solution 1.:
my $str = 'ttt, 2';
my $result;
# trivial solution w/capturing
($result) = $str=~/\w{3}, (\d)/ and print "1. $result\n";
If you want to do some more fancy stuff, you
could 'ifify' the whole expression with
a "positive lookbehind", like:
# lookbehind (?<= ...), no capturing, /g in list context
($result) = $str=~/(?<=\w{3}, )\d/g and print "2. $result\n";
Regards
M.
Re: conditional regular expressions
am 13.08.2007 18:47:17 von xhoster
Morfys wrote:
> hi,
>
> I was having trouble understanding how regular conditional expressions
> work. In particular, in this piece of code:
>
> $str = "ttt, 2";
>
> if(($result) = $str =~ /\w\w\w(?(?=, )(\d))/){
>
> print "$result\n";
>
> }
>
> I don't understand why there is empty output versus "2".
?= is zero-width, meaning that after the ', ' matches, the \d is left
to match starting at the same place, namely, at the ','. Since ',' is not
a \d, it can't match.
>
> The desired effect is that $result contain the digit following ", " if
> it exists in the string.
Isn't that just what the simple /\w\w\w, (\d)/ would do?
Xho
--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
Re: conditional regular expressions
am 14.08.2007 10:47:35 von Morfys
Thanks a lot! Indeed my problem was that ?= is zero-width.
> > The desired effect is that $result contain the digit following ", " if
> > it exists in the string.
>
> Isn't that just what the simple /\w\w\w, (\d)/ would do?
In fact, the example I gave was just to simplify things so that my
question could be clear. In my "real" regular expression, I need to
parse strings like
"open(X,X)"
and
"open(X,X,X)"
and so the conditional seems necessary.
Re: conditional regular expressions
am 14.08.2007 12:58:55 von Tad McClellan
Morfys wrote:
>> > The desired effect is that $result contain the digit following ", " if
>> > it exists in the string.
>>
>> Isn't that just what the simple /\w\w\w, (\d)/ would do?
>
> In fact, the example I gave was just to simplify things so that my
> question could be clear. In my "real" regular expression, I need to
> parse strings like
> "open(X,X)"
> and
> "open(X,X,X)"
$_ = 'open(X,Y,Z)';
my @parts = /(\w+)(?=[,)])/g;
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
Re: conditional regular expressions
am 14.08.2007 13:13:00 von Gunnar Hjalmarsson
Morfys wrote:
> In fact, the example I gave was just to simplify things so that my
> question could be clear.
Then you didn't succeed very well. :)
> In my "real" regular expression, I need to parse strings like
> "open(X,X)"
> and
> "open(X,X,X)"
> and so the conditional seems necessary.
my $str = 'open(4,5,6)';
if ( my ($digits) = $str =~ /open\((\d(?:,\d)*)\)/ ) {
my @result = split /,/, $digits;
print "@result\n";
}
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Re: conditional regular expressions
am 14.08.2007 13:24:45 von Mirco Wahab
Morfys wrote:
> In fact, the example I gave was just to simplify things so that my
> question could be clear. In my "real" regular expression, I need to
> parse strings like
> "open(X,X)"
> and
> "open(X,X,X)"
> and so the conditional seems necessary.
.... condition to branch on what?
I could understand this intend
to match a string like
"open(X,X,X), 3"
or
"open(X,X), 2"
but your example doesn't provide
an ample motivation for introducting
conditionals.
Regards
M.
Re: conditional regular expressions
am 14.08.2007 13:27:48 von Mirco Wahab
Tad McClellan wrote:
> Morfys wrote:
>> "open(X,X)"
>> and
>> "open(X,X,X)"
> $_ = 'open(X,Y,Z)';
> my @parts = /(\w+)(?=[,)])/g;
Just out of couriosity, what's the
purpose of these fancy parenthesis
around \w+ ? Is there any hidden
mechanics to use them this way?
Regards
M.
Re: conditional regular expressions
am 14.08.2007 13:31:45 von Gunnar Hjalmarsson
Tad McClellan wrote:
> Morfys wrote:
>> I need to parse strings like
>> "open(X,X)"
>> and
>> "open(X,X,X)"
>
> $_ = 'open(X,Y,Z)';
> my @parts = /(\w+)(?=[,)])/g;
You don't need both capturing parentheses and the "(?= ... )" part, do you?
my @parts = /(\w+)[,)]/g;
or
my @parts = /\w+(?=[,)])/g;
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
Re: conditional regular expressions
am 14.08.2007 14:16:40 von anno4000
Mirco Wahab wrote in comp.lang.perl.misc:
> Tad McClellan wrote:
> > Morfys wrote:
> >> "open(X,X)"
> >> and
> >> "open(X,X,X)"
> > $_ = 'open(X,Y,Z)';
> > my @parts = /(\w+)(?=[,)])/g;
>
> Just out of couriosity, what's the
> purpose of these fancy parenthesis
> around \w+ ? Is there any hidden
> mechanics to use them this way?
Hmm? What's fancy about them. They're normal capturing parentheses.
Anno
Re: conditional regular expressions
am 14.08.2007 14:35:44 von Mirco Wahab
anno4000@radom.zrz.tu-berlin.de wrote:
> Mirco Wahab wrote in comp.lang.perl.misc:
>> Tad McClellan wrote:
>>> Morfys wrote:
>>>> "open(X,X)"
>>>> and
>>>> "open(X,X,X)"
>>> $_ = 'open(X,Y,Z)';
>>> my @parts = /(\w+)(?=[,)])/g;
>> Just out of couriosity, what's the
>> purpose of these fancy parenthesis
>> around \w+ ? Is there any hidden
>> mechanics to use them this way?
>
> Hmm? What's fancy about them. They're normal capturing parentheses.
I wouldn't consider normal in the said example,
therefore my question: "does the perl regex
engine distinguish internal" between
my @foo = /\w+(?= bar)/g;
and
my @foo = /(\w+)(?= bar)/g;
I can't answer this for myself,
thats the reason I asked Tad.
Regards
M.
Re: conditional regular expressions
am 14.08.2007 15:08:36 von anno4000
Mirco Wahab wrote in comp.lang.perl.misc:
> anno4000@radom.zrz.tu-berlin.de wrote:
> > Mirco Wahab wrote in comp.lang.perl.misc:
> >> Tad McClellan wrote:
> >>> Morfys wrote:
> >>>> "open(X,X)"
> >>>> and
> >>>> "open(X,X,X)"
> >>> $_ = 'open(X,Y,Z)';
> >>> my @parts = /(\w+)(?=[,)])/g;
> >> Just out of couriosity, what's the
> >> purpose of these fancy parenthesis
> >> around \w+ ? Is there any hidden
> >> mechanics to use them this way?
> >
> > Hmm? What's fancy about them. They're normal capturing parentheses.
>
> I wouldn't consider normal in the said example,
I'm still not sure *why* you'd consider them abnormal. It's true that
/g makes them redundant, but they function as they always do.
> therefore my question: "does the perl regex
> engine distinguish internal" between
>
> my @foo = /\w+(?= bar)/g;
> and
> my @foo = /(\w+)(?= bar)/g;
>
> I can't answer this for myself,
> thats the reason I asked Tad.
I can't speak for Tad, but the parens make the capture more robust
while you change parts of the regex around.
Anno
Re: conditional regular expressions
am 14.08.2007 16:04:50 von Morfys
> I could understand this intended
> to match a string like
>
> "open(X,X,X), 3"
> or
> "open(X,X), 2"
that's what I meant. ;)
Re: conditional regular expressions
am 14.08.2007 16:24:45 von Mirco Wahab
Morfys wrote:
>> I could understand this intended
>> to match a string like
>>
>> "open(X,X,X), 3"
>> or
>> "open(X,X), 2"
>
> that's what I meant. ;)
OK, then there are some solutions available,
my first trial would be something like:
....
my @strings = (
"open(X,X,X), 1",
"open(X,X,X), 3",
"open(X,X,X), 31",
"open(X,X), 2",
"open(X,X), 23",
"open(X,X), 32" );
my $n;
no strict 'refs';
my $rg = qr{\(
(\w?)[,)]?
(\w?)[,)]?
(\w?)[,)]?
(\w?)[,)]?
,\s+
(??{ scalar(grep ${$_} ,1..@+) })
$
}x;
print "\n$_" for grep /$rg/, @strings
....
which is still simple and will work up to four
"entities". To make a more comprehensive version -
is left to you ;-)
The "Trick" is to check the capture groups (\w)
for 'trueness' (in grep) and take the 'number'
of positively grepped items as the content
(will be "2" or "3") of the dynamic regex
part (??{ ... }).
Regards
M.
Re: conditional regular expressions
am 14.08.2007 20:29:42 von Bill H
On Aug 14, 10:24 am, Mirco Wahab wrote:
> Morfys wrote:
> >> I could understand this intended
> >> to match a string like
>
> >> "open(X,X,X), 3"
> >> or
> >> "open(X,X), 2"
>
> > that's what I meant. ;)
>
> OK, then there are some solutions available,
> my first trial would be something like:
>
> ...
> my @strings = (
> "open(X,X,X), 1",
> "open(X,X,X), 3",
> "open(X,X,X), 31",
> "open(X,X), 2",
> "open(X,X), 23",
> "open(X,X), 32" );
>
> my $n;
> no strict 'refs';
> my $rg = qr{\(
> (\w?)[,)]?
> (\w?)[,)]?
> (\w?)[,)]?
> (\w?)[,)]?
> ,\s+
> (??{ scalar(grep ${$_} ,1..@+) })
> $
> }x;
>
> print "\n$_" for grep /$rg/, @strings
> ...
>
> which is still simple and will work up to four
> "entities". To make a more comprehensive version -
> is left to you ;-)
>
> The "Trick" is to check the capture groups (\w)
> for 'trueness' (in grep) and take the 'number'
> of positively grepped items as the content
> (will be "2" or "3") of the dynamic regex
> part (??{ ... }).
>
> Regards
>
> M.
I know this may not be the most elegant way of doing it, but, using
the examples given couldn't you just do this:
my @strings = (
"open(X,X,X), 1",
"open(X,X,X), 3",
"open(X,X,X), 31",
"open(X,X), 2",
"open(X,X), 23",
"open(X,X), 32" );
foreach $temp (@strings)
{
@dbf=split(/\,/,$temp);
$numpart[@numpart] = $dbf[@dbf - 1];
}
And @numpart would hold all the decimal parts.
Bill H