string comparison

  • Thread starter Shashank Khanvilkar
  • Start date
S

Shashank Khanvilkar

Hi,
I think i am doing something wrong here. Can anyone please let me know what

$a = "apple";

if ($a eq ('apple')){
print "right choice\n";
}else{
print "wrong choice\n";
}

This above prints "right choice". But the below prints "wrong choice".
How can i make the below program print "right choice".


$a = "apple";

if ($a eq ('apple'|'banana')){
print "right choice\n";
}else{
print "wrong choice\n";
}
 
B

Babacio

Shashank Khanvilkar said:
How can i make the below program print "right choice".


$a = "apple";

if ($a eq ('apple'|'banana')){
print "right choice\n";
}else{
print "wrong choice\n";
}

Try to write $a='cq~moa'; instead of $a='apple';

This should work, yes sir, because the value of 'apple'|'banana' is
'cq~moa'.

But if I guess what you really want to do, try that :

if ($a eq 'apple' || $a eq 'banana') { etc }

And read some documentation, this is in the second chapter of any
introduction to perl. For complete information about the operators,
perldoc perlop.
 
P

Paul Lalli

Shashank said:
Hi,
I think i am doing something wrong here. Can anyone please let me know what

$a = "apple";

if ($a eq ('apple')){

Those inner parentheses are unneeded, and serve only to clutter the
expression.
print "right choice\n";
}else{
print "wrong choice\n";
}

This above prints "right choice". But the below prints "wrong choice".
How can i make the below program print "right choice".

$a = "apple";

if ($a eq ('apple'|'banana')){
print "right choice\n";
}else{
print "wrong choice\n";
}

The eq operator tests for equality. The | operator does a bit-wise
'or' on its arguments. Therefore, the string you are testing for
equality to eq is: 'cq~moa' ('a' | 'b' = 'c', 'p' | 'a' = 'q',
etcetera).

I *think* what you're looking for is a regular expression, or pattern
match. You want to determine if $a contains either of your two
strings:

if ($a =~ /apple|banana/) {
print "\$a contains either 'apple' or 'banana'\n";
}

Read more on regular expressions in a variety of documentation:
perldoc perlre
perldoc perlretut
perldoc perlreref
perldoc perlrequick


Paul Lalli
 
G

Gunnar Hjalmarsson

Babacio said:
But if I guess what you really want to do, try that :

if ($a eq 'apple' || $a eq 'banana') { etc }

or this:

if ( grep $a eq $_, ('apple', 'banana') ) {

(perldoc -f grep)
And read some documentation,

Indeed.
 
T

Tassilo v. Parseval

Also sprach Anno Siegel:
...or use Quantum::Superposition

Yuck. I'd suggest

use List::MoreUtils qw/any/;

if (any { $a eq $_ } qw/apple banana/) {

Tassilo
 
D

Dave Weaver

Tassilo v. Parseval said:
Also sprach Anno Siegel:


Yuck. I'd suggest

use List::MoreUtils qw/any/;

if (any { $a eq $_ } qw/apple banana/) {

If I was the code maintainer, I'd prefer to see:

if ( $a eq 'apple' or $a eq 'banana' ) {
...

It's concise, easy to read (it's practically English), and no modules required.

Of course, as the list of fruit grows longer, this becomes slighly
less appealing, but I missed the beginning of this thread, so I'm not
sure if that's relevant. If it was a long list of fruit I'd probably
put the details of the comparison into a subroutine:

if ( in_list( $a, @fruit ) ) {
...
}

The implementation of in_list() is left as an excercise for the reader.
 
A

Anno Siegel

Dave Weaver said:
If I was the code maintainer, I'd prefer to see:

if ( $a eq 'apple' or $a eq 'banana' ) {
...

It's concise, easy to read (it's practically English), and no modules required.

Of course, as the list of fruit grows longer, this becomes slighly
less appealing, but I missed the beginning of this thread, so I'm not
sure if that's relevant. If it was a long list of fruit I'd probably
put the details of the comparison into a subroutine:

For a long list the standard solution is a hash:

my %is_fruit = (
apple => 1,
banana => 1,
# ...
);
if ( $is_fruit{ $a} ) {
# ...
}

Anno
 
D

Dr.Ruud

Dave Weaver schreef:
If I was the code maintainer, I'd prefer to see:

if ( $a eq 'apple' or $a eq 'banana' ) {


This looks too great:

if ( $a in ('apple', 'banana') ) {

so how about the maintainability of:

my @fruit = qw(apple banana);

my $regex = '^('. join('|', @fruit) .')$';

if ( $a =~ /$regex/ ) {
 
J

Jürgen Exner

Dr.Ruud said:
Dave Weaver schreef:
If I was the code maintainer, I'd prefer to see:

if ( $a eq 'apple' or $a eq 'banana' ) {
[...]
so how about the maintainability of:

my @fruit = qw(apple banana);

my $regex = '^('. join('|', @fruit) .')$';

if ( $a =~ /$regex/ ) {

Two problems:
- REs are the wrong tool to do string comparion
- and they will yield wrong results as soon as the search text contains
RE-special characters

jue
 
D

Dr.Ruud

Jürgen Exner:
Dr.Ruud:
my @fruit = qw(apple banana);

my $regex = '^('. join('|', @fruit) .')$';

if ( $a =~ /$regex/ ) {

Two problems:
- REs are the wrong tool to do string comparion


What are the big wrongs?

- and they will yield wrong results as soon as the search text
contains RE-special characters

In procmail I can use $\var to (almost) unharm this. Of course there
is no need to show a Perl way to do something similar, if the first
problem is that big.
 
A

Anno Siegel

Dr.Ruud said:
Dave Weaver schreef:



This looks too great:

if ( $a in ('apple', 'banana') ) {

so how about the maintainability of:

my @fruit = qw(apple banana);

my $regex = '^('. join('|', @fruit) .')$';

if ( $a =~ /$regex/ ) {

It's fine, though someone might come up with "banana[puertorico]" vs.
"banana[brazil]" and mess up the regex. I'd also prefer non-capturing
parentheses:

my $regex = '^(?:' . join( '|', map quotemeta, @fruit) . ')$';

Anno
 
J

Jürgen Exner

Dr.Ruud said:
Jürgen Exner:
Two problems:
- REs are the wrong tool to do string comparion


What are the big wrongs?


You don't use a gun to swat flies. You use a fly swater.

Perl has a perfectly fine eq operator for comparing strings. There is no
need to launch the big and expensive RE gun and then jump through hoops to
"make it work" (e.g. for RE special characters).
Would be interesting to benchmark a simple eq in a loop versus the
concatenated or'ed REs. My gut feeling is that the loop with eq will be much
faster

jue
 
D

Dr.Ruud

Jürgen Exner schreef:
Perl has a perfectly fine eq operator for comparing strings. There is
no need to launch the big and expensive RE gun

OK, but that argument vaporizes if the RE was or will be loaded for
other parts of the program anyway.
and then jump through
hoops to "make it work" (e.g. for RE special characters).

No need to jump through hoops:

if ($a =~ m/\A(apple
|banana
|orange
)
\z/x) {
(untested)

Would be interesting to benchmark a simple eq in a loop versus the
concatenated or'ed REs. My gut feeling is that the loop with eq will
be much faster

Compiled simple regexes are also very fast. I'll try benchmark later.
 

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

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top