How to match characters in different locations within string

J

Jack

Hello..

I have:
$temp = 'with 855 and 990';

How do I return true or false (ideally through a regular expression)
the existence of both 'with' and 'and' inside the string ? I have
messed around with it for a while and cant figure it out, assistance
would be great. Also how does it change if I test for 3 particular
words as opposed to 2..?

Thank you,

Jack
 
U

usenet

Jack said:
How do I return true or false (ideally through a regular expression)
the existence of both 'with' and 'and' inside the string ?

Hello, welcome to Perl and to CLPMIsc. As you seem new to both, you
are probably not aware that this particular newsgroup has posting
guidelines; you may find these at
http://www.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html
I have messed around with it for a while and cant figure it out

Are you just guessing at a solution, or have you read the docs for
regular expressions (perldoc perlre)?
assistance would be great.

Sure, we'll be glad to help you fix you code (but you probably won't
find someone here to write it for you). Just show us what you've done
so far. This gives us a frame of reference to what level of
understanding you have so we can adapt our answer accordingly.
 
G

Gunnar Hjalmarsson

Jack said:
$temp = 'with 855 and 990';

How do I return true or false (ideally through a regular expression)
the existence of both 'with' and 'and' inside the string ?

sub isWords {
local $_ = $_[0];
/\bwith\b/ && /\band\b/ ? 1 : 0;
}

print "True\n" if isWords($temp);
 
D

Dr.Ruud

Gunnar Hjalmarsson schreef:
sub isWords {
local $_ = $_[0];

That is a copy, but I have often wondered why a localized $_ alias of
$_[0] isn't implicit for a sub.

Is there a clear way to make $_ a localized alias of $_[0]?
With "clear" I mean much clearer than an enclosing "for ( $_[0] ){}"
would.
 
B

Brian McCauley

Gunnar said:
Jack said:
$temp = 'with 855 and 990';

How do I return true or false (ideally through a regular expression)
the existence of both 'with' and 'and' inside the string ?

sub isWords {
local $_ = $_[0];

This is a bug waiting to happen.

If isWords() is called in a contest where $_ happens to be alaised to
an element of a tied aggregate then nasty things happen when you do
local($_).

Always use for() or local(*_) to localise changes to $_.
 
B

Brian McCauley

Dr.Ruud said:
Is there a clear way to make $_ a localized alias of $_[0]?
With "clear" I mean much clearer than an enclosing "for ( $_[0] ){}"
would.

I find that perfectly clear. It's just a mindset thing I guess.
 
D

Dr.Ruud

Brian McCauley schreef:
Dr.Ruud:
Is there a clear way to make $_ a localized alias of $_[0]?
With "clear" I mean much clearer than an enclosing "for ( $_[0] ){}"
would.

I find that perfectly clear. It's just a mindset thing I guess.

Other example:

for my $i (0 .. $#subst)
{
for my $s ($_ )
{
for my $a ($subst[$i])
{
for my $f ($a->[0])
{
for my $t ($a->[1])
{
...
} } } } }


which makes me think about

for my $i (0 .. $#subst)
{
alias ($s, $a, $f, $t) ($_, $subst[$i], $a->[0], $a->[1])
{
...
}
}
 
G

Gunnar Hjalmarsson

Brian said:
Gunnar said:
sub isWords {
local $_ = $_[0];

This is a bug waiting to happen.

If isWords() is called in a contest where $_ happens to be alaised to
an element of a tied aggregate then nasty things happen when you do
local($_).

I don't understand that. This code:

my $temp = 'with 855 and 990';

sub isWords {
local $_ = $_[0];
/\bwith\b/ && /\band\b/ ? 1 : 0;
}

for ('hello') {
print "True\n" if isWords($temp);
print "$_\n";
}

outputs:
True
hello

as I would have expected.
Always use for() or local(*_) to localise changes to $_.

If I exchange 'local $_' in the above example for 'local *_', the $_
variable is empty within the isWords() function.
 
J

Jack

Hello, welcome to Perl and to CLPMIsc. As you seem new to both, you
are probably not aware that this particular newsgroup has posting
guidelines; you may find these at
http://www.augustmail.com/~tadmc/clpmisc/clpmisc_guidelines.html


Are you just guessing at a solution, or have you read the docs for
regular expressions (perldoc perlre)?

have I read the docs ? Of course I have - why dont you tell me how with
a reg. expression to accomplish this - obviously you cant, nor could I
for hours. I think maybe you should read the docs and answer the
question. How about it.
 
B

Ben Morrow

Quoth Gunnar Hjalmarsson said:
Brian said:
Gunnar said:
sub isWords {
local $_ = $_[0];

This is a bug waiting to happen.

If isWords() is called in a contest where $_ happens to be alaised to
an element of a tied aggregate then nasty things happen when you do ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
local($_).

I don't understand that. This code:

doesn't test what Brian was talking about. :) I can't remember the
details, but if you just localize a tied $_ there is some confusion
about the tie magic (IIRC it is not restored correctly at the end of the
scope, but I may be wrong).
If I exchange 'local $_' in the above example for 'local *_', the $_
variable is empty within the isWords() function.

.... so you need to replace

local $_ = ...;

with

local *_;
$_ = ...;

or

for (...) {

:)

Ben
 
M

Mumia W.

Dr.Ruud said:
Gunnar Hjalmarsson schreef:
sub isWords {
local $_ = $_[0];

That is a copy, but I have often wondered why a localized $_ alias of
$_[0] isn't implicit for a sub.

Is there a clear way to make $_ a localized alias of $_[0]?
With "clear" I mean much clearer than an enclosing "for ( $_[0] ){}"
would.

There is no way, but you can use a local reference to the array:

local $_ = \@_;
print $_->[0];

That's the closest I can find to what you want.
 
D

Dr.Ruud

Brian McCauley schreef:
Dr.Ruud:
Is there a clear way to make $_ a localized alias of $_[0]?
With "clear" I mean much clearer than an enclosing "for ( $_[0] ){}"
would.

I find that perfectly clear. It's just a mindset thing I guess.

OK. After "use Data::Alias" one can do:

alias local $_ = $_[0];

or alternatively:

alias local ($_) = @_;

but I haven't investigated "it-tied" yet.
 
D

Dr.Ruud

Mumia W. schreef:
Dr.Ruud:
Gunnar Hjalmarsson:
sub isWords {
local $_ = $_[0];

That is a copy, but I have often wondered why a localized $_ alias of
$_[0] isn't implicit for a sub.

Is there a clear way to make $_ a localized alias of $_[0]?
With "clear" I mean much clearer than an enclosing "for ( $_[0] ){}"
would.

There is no way, but you can use a local reference to the array:

local $_ = \@_;
print $_->[0];

That's the closest I can find to what you want.


Well, I might want a localized $_ as alias of $_[0] for every sub. Are
there any good reasons against it?


But also see the line with the arrow below.

#!/usr/bin/perl
use strict ;
use warnings ;

use Data::Alias ;

sub demo
{
print "demo-0: \$_<$_>, \@_<@_>\n" ;

alias local $_ = $_[0]; # <----

print "demo-1: \$_<$_>, \@_<@_>\n" ;

$_ = '3rd' ;

print "demo-2: \$_<$_>, \@_<@_>\n" ;
}

my $x ;
print "\n" ;

$_ = '1st' ;
$x = '2nd' ;
print "\$_<$_>\n" ;
print "\$x<$x>\n" ;

demo $x, 'y', 'z' ;
print "\$x<$x>\n" ;
print "\$_<$_>\n" ;
print "\n" ;

demo $_, 8, 9 ;
print "\$_<$_>\n" ;
print "\n" ;
__END__


That prints:

$_<1st>
$x<2nd>
demo-0: $_<1st>, @_<2nd y z>
demo-1: $_<2nd>, @_<2nd y z>
demo-2: $_<3rd>, @_<3rd y z>
$x<3rd>
$_<1st>

demo-0: $_<1st>, @_<1st 8 9>
demo-1: $_<1st>, @_<1st 8 9>
demo-2: $_<3rd>, @_<3rd 8 9>
$_<3rd>

Looks to me to behave as should be expected.
 
L

Lionel

Jack said:
have I read the docs ? Of course I have - why dont you tell me how with
a reg. expression to accomplish this - obviously you cant, nor could I
for hours. I think maybe you should read the docs and answer the
question. How about it.

Ahhhh, although I object to posts with the tone of the previous one, as
the OP asking for a solution you should be a little more grateful and
polite. No one HAS to give you a solution, so any answers are a favour
and you should see them that way.

Lionel.
 
B

Ben Morrow

Quoth "Dr.Ruud said:
Well, I might want a localized $_ as alias of $_[0] for every sub. Are
there any good reasons against it?

Subs that want to take $_ as a default value.
 
J

John W. Krahn

Jack said:
I have:
$temp = 'with 855 and 990';

How do I return true or false (ideally through a regular expression)
the existence of both 'with' and 'and' inside the string ? I have
messed around with it for a while and cant figure it out, assistance
would be great.

$ perl -le'
$temp = q[with 855 and 990];
print $temp =~ /(?=.*\bwith\b)(?=.*\band\b)/ ? q[TRUE] : q[FALSE];
'
TRUE
Also how does it change if I test for 3 particular
words as opposed to 2..?

$ perl -le'
$temp = q[with 855 and 990];
print $temp =~ /(?=.*\bwith\b)(?=.*\band\b)(?=.*\b855\b)/ ? q[TRUE] : q[FALSE];
'
TRUE



John
 
G

Gunnar Hjalmarsson

Ben said:
Quoth Gunnar Hjalmarsson said:
Brian said:
Gunnar Hjalmarsson wrote:

sub isWords {
local $_ = $_[0];

This is a bug waiting to happen.

If isWords() is called in a contest where $_ happens to be alaised to
an element of a tied aggregate then nasty things happen when you do ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
local($_).

I don't understand that. This code:

doesn't test what Brian was talking about. :)

I see. Guess it's the expression "tied aggregate" I don't understand, then.

If someone could post an applicable example, it would be much appreciated.
... so you need to replace

local $_ = ...;

with

local *_;
$_ = ...;

Well, that seems not to be enough in this case. Since I want to copy
$_[0] to $_, I also need a temporary variable:

sub isWords {
my $tmp = $_[0];
local *_;
$_ = $tmp;
/\bwith\b/ && /\band\b/ ? 1 : 0;
}
or

for (...) {

sub isWords {
for ( $_[0] ) {
return 1 if /\bwith\b/ && /\band\b/;
}
}

Less clumsy, it seems...
 
D

Dr.Ruud

Ben Morrow schreef:
Dr.Ruud:
Well, I might want a localized $_ as alias of $_[0] for every sub.
Are there any good reasons against it?

Subs that want to take $_ as a default value.

An exception is obviously made for a call without arguments, because
then there would not be a $_[0].

That leaves subs where $_ is the default for another argument but the
first. Maybe an attribute could be used for those.

sub my_split : respect_it
{
@_ > 1 and alias local $_ = $_[1] ;
...
}
 
B

Ben Morrow

Quoth "Dr.Ruud said:
Ben Morrow schreef:
Dr.Ruud:
Well, I might want a localized $_ as alias of $_[0] for every sub.
Are there any good reasons against it?

Subs that want to take $_ as a default value.

An exception is obviously made for a call without arguments, because
then there would not be a $_[0].

That leaves subs where $_ is the default for another argument but the
first. Maybe an attribute could be used for those.

You're not getting it. The calling conventions *can't* be changed now,
because it breaks back-compatibility. c.f. Perl6.

Ben
 
B

Ben Morrow

Quoth Gunnar Hjalmarsson said:
Ben said:
Quoth Gunnar Hjalmarsson said:
Brian McCauley wrote:
Gunnar Hjalmarsson wrote:

sub isWords {
local $_ = $_[0];

This is a bug waiting to happen.

If isWords() is called in a contest where $_ happens to be alaised to
an element of a tied aggregate then nasty things happen when you do ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
local($_).

I don't understand that. This code:

doesn't test what Brian was talking about. :)

I see. Guess it's the expression "tied aggregate" I don't understand, then.

Brian means when $_ is aliased (by for, or whatever) to an element of a
tied array or hash.
... so you need to replace

local $_ = ...;

with

local *_;
$_ = ...;

Well, that seems not to be enough in this case. Since I want to copy
$_[0] to $_, I also need a temporary variable:

sub isWords {
my $tmp = $_[0];
local *_;
$_ = $tmp;
/\bwith\b/ && /\band\b/ ? 1 : 0;
}

Whoops! Didn't spot that... try

local *_ = \$_[0];

....although I'd not be certain this actually localises all of *_. Brian,
can you help me here?

Ben
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top