Matching strings with index – getting extra matches.

G

G

I’m looping through a sales_file looking for matches. The file
has a number of entries such as the following:

sales item aaa | m423a
sales item bbb | m423
sales item ccc | m423b
sales item ddd | 423

These refer to sales_item and code respectively.

Here is the code segment:

open FILE, "<$sales_file";
while (<FILE>) {
($sales_item, $code) = split /\|/;
if (index($code, $entered_code) != -1) {
$list .= "<br>" if ($list);
$list .= $sales_item;
}
} # while
close FILE;

The problem is, if the $entered_code is 423 I get matches for all 4
when I would only want matches for the fourth sales item “sales
item ddd” line. Similarly, an $entered_code of m423 would match
the first 3. Any suggestions on how I can get the right matches,
keeping in mind that I would prefer to do it in code, and not alter
the sales_file.

Thanks,

C
 
P

Paul Lalli

I’m looping through a sales_file looking for matches. The file
has a number of entries such as the following:

sales item aaa | m423a
sales item bbb | m423
sales item ccc | m423b
sales item ddd | 423

These refer to sales_item and code respectively.

Here is the code segment:

open FILE, "<$sales_file";
while (<FILE>) {
($sales_item, $code) = split /\|/;
if (index($code, $entered_code) != -1) {
$list .= "<br>" if ($list);
$list .= $sales_item;
}
} # while
close FILE;

The problem is, if the $entered_code is 423 I get matches for all 4
when I would only want matches for the fourth sales item “sales
item ddd” line. Similarly, an $entered_code of m423 would match
the first 3. Any suggestions on how I can get the right matches,
keeping in mind that I would prefer to do it in code, and not alter
the sales_file.

Replace the index() line with
if ($code =~ /^\s*$entered_code\s*$/) {

This will search the $code line for 'beginning of string, possible white
space, the code, possible white space, end of string', rather than just
"the code anywhere within the string" as you're doing now.

Paul Lalli
 
G

gnari

[problem with index not matching string exactly]
sales item aaa | m423a
sales item bbb | m423
sales item ccc | m423b
sales item ddd | 423

if there is allways space around the '|' you should
have them in your split
...
($sales_item, $code) = split /\|/;
($sales_item, $code) = split / \| /;
if (index($code, $entered_code) != -1) {


if there is no trailing space after the code then
if ($code eq $entered_code) {

if on the other hand, your data is dirty with
whilespace, you are better off with a
regexp match as someone else suggested
or even replace the split with a match:

($sales_item, $code) = /^\s*(.+?)\s*\|\s*(.+?)\s*/;
if ($code eq $entered_code) {

gnari
 
T

Tad McClellan

G said:
open FILE, "<$sales_file";


You should always, yes *always*, check the return value from open():

open FILE, "<$sales_file" or die "could not open '$sales_file' $!";
 
G

G

gnari said:
[problem with index not matching string exactly]
sales item aaa | m423a
sales item bbb | m423
sales item ccc | m423b
sales item ddd | 423

if there is allways space around the '|' you should
have them in your split
...
($sales_item, $code) = split /\|/;
($sales_item, $code) = split / \| /;
if (index($code, $entered_code) != -1) {


if there is no trailing space after the code then
if ($code eq $entered_code) {

if on the other hand, your data is dirty with
whilespace, you are better off with a
regexp match as someone else suggested
or even replace the split with a match:

($sales_item, $code) = /^\s*(.+?)\s*\|\s*(.+?)\s*/;
if ($code eq $entered_code) {

gnari

Thanks for the suggestions so far, but I now realize I the sample text
file was flawed. For one there is Never white space around the '|'.
Secondly a line could have multiple codes but no duplicates(on that
line only). The sample file should have looked as follows:

sales item aaa|543,m423a
sales item bbb|m423,543 'Note how code 543 is on the 1st 2nd
line.
sales item ccc|m423b
sales item ddd|423,423b,m523,652

Given that the above has changed how could I get a match. e.g. a code
of 423 should return the description in line 4 "sales item ddd" Where
m423 only matches the 3rd line. etc.

Thanks,

C
 
B

Ben Morrow

Thanks for the suggestions so far, but I now realize I the sample text
file was flawed. For one there is Never white space around the '|'.
Secondly a line could have multiple codes but no duplicates(on that
line only). The sample file should have looked as follows:

sales item aaa|543,m423a
sales item bbb|m423,543 'Note how code 543 is on the 1st 2nd
line.
sales item ccc|m423b
sales item ddd|423,423b,m523,652

Given that the above has changed how could I get a match. e.g. a code
of 423 should return the description in line 4 "sales item ddd" Where
m423 only matches the 3rd line. etc.

my $code = 'm423';
while (<>) {
my ($item, $codes) = split /\|/;
my @codes = split /,/, $codes;
print $item if grep { $_ eq $code } @codes;
}

alternatively:

/(.*) \| (?:.*,|) \Q$code\E (?:,|$)/x and print $1 while <>;

Ben
 
G

G

Ben Morrow said:
my $code = 'm423';
while (<>) {
my ($item, $codes) = split /\|/;
my @codes = split /,/, $codes;
print $item if grep { $_ eq $code } @codes;
}
I finally gave this code a try, but it only partially works. For
instance a code of m423b will not pull up any results. Neither will
m523. My guess is we are not splitting things out right: my
@codes = split /,/, $codes;

Thanks,

C
 
B

Ben Morrow

chomp;


I finally gave this code a try, but it only partially works. For
instance a code of m423b will not pull up any results. Neither will
m523. My guess is we are not splitting things out right: my
@codes = split /,/, $codes;

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,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top