Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Is it Possible to match contents in hash via a Regex?

by brassmon_k (Sexton)
on Jan 02, 2002 at 22:59 UTC ( #135759=perlquestion: print w/ replies, xml ) Need Help??
brassmon_k has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

Ran into a road block while writing some code and I can't figure out how to figure it out. The problem: I have essentially DB oriented code and it has a built-in menu and goes through the text and reports the results back to the searcher. However this text is just a bunch of numbers (23 fields all separated by a single space and fields can range from 2 to 16 digits in length) Now for field 15 I set up a hash with the values of the numbers that reflects regular understandle text so field 15 will have meaning to the searcher instead of just being numbers. However I can't figure out how to get the damn line to print with the Decoded value in the line. Here is the script:
#!/usr/bin/perl -w use strict; my $datemin; my $datemax; my $timemin; my $timemax; my $choice; my $msisdn; my $range; my $rangex; my %TOC; %TOC = ( 'DID' => "Digit Feed Recieved", 'ETE' => "No digit feed/calle +r enters mailbox number", 'ODL' => "Outidal Delivery", 'ODN' => "Outdial Notification", 'DEP' => "Deposit Only", 'RET' => "Re +trieval Only", 'SMD' => "SMDI serially integrated trunk", 'PAG' => "Page delivery", 'ISI' => "Infoserv Recording", 'TAS' => "TAS + Call", 'TTT' => "Trunk to trunk transfer", 'PBX' => "PBX type transfer", 'CMC' => "Constant Touch", 'CMO' => "Con +stant Touch Outdial notification" ); print "Your Options Are:\n"; print "\n"; print "DateSearch Only = 'd'\n"; print "TimeSearch Only = 't'\n"; print "Msisdn Search Only = 'm'\n"; print "Date & Time Search = 'b'\n"; print "\n"; do { print "Select Your Option:> (d, t, m, b)"; chomp($choice = <STDIN>); } until ($choice =~ /^[DdTtMmBb]/); if ($choice =~ /^[Dd]/) { $range = <STDIN>; ($datemin, $datemax) = split /-/, $range; # Squeeze out leading and trailing spaces $datemin =~ s/^\s+//; $datemin =~ s/\s+$//; $datemax =~ s/^\s+//; $datemax =~ s/\s+$//; print "beg: $datemin end: $datemax\n"; print "Matches\n-------\n"; open(FILE, "/dave/MVPTEST/mvpdoc"); while (<FILE>) { chomp; if ($_ =~ /(\d{4})\s(\d{5})\s(\d{3})\s(\d{2})\s(\d{2}\ +/\d{2}\/\d{2})\s(\d{2}\:\d{2}\:\d{2})\s(\d{3})\s(\d{2})\s(\S+)\s(\d{2 +})\s(\d{2})\s(\d{2})\s(\d{2})\s(\w{3})$/) { if (($5 ge $datemin) && ($5 le $datemax)) { print "$_\n"; } } } } if ($choice =~ /^[Tt]/) { $rangex = <STDIN>; ($timemin, $timemax) = split /-/, $rangex; # Squeeze out leading and trailing spaces $timemin =~ s/^\s+//; $timemin =~ s/\s+$//; $timemax =~ s/^\s+//; $timemax =~ s/\s+$//; print "beg: $timemin end: $timemax\n"; print "Matches\n-------\n"; open(FILE, "/dave/MVPTEST/mvpdoc"); while (<FILE>) { chomp; if ($_ =~ /(\d{4})\s(\d{5})\s(\d{3})\s(\d{2})\s(\d{2}\ +/\d{2}\/\d{2})\s(\d{2}\:\d{2}\:\d{2})/) { if (($6 ge $timemin) && ($6 le $timemax)) { print "$_\n"; } } } } elsif ($choice =~ /^[Mm]/) { chomp($msisdn = <STDIN>); print "Matches\n-------\n"; open(FILE, "/dave/MVPTEST/mvpdoc"); while (<FILE>) { chomp; if ($_ =~ /(\d{4})\s(\d{5})\s(\d{3})\s(\d{2})\s(\d{2}\/\d{ +2}\/\d{2})\s(\d{2}\:\d{2}\:\d{2})\s(\d{2})\s(\S+)/) { if ($8 =~ $msisdn) { print "$_\n"; } } } } elsif ($choice =~ /^[Bb]/) { $range = <STDIN>; $rangex = <STDIN>; # Break up the range ($datemin, $datemax) = split /-/, $range; ($timemin, $timemax) = split /-/, $rangex; # Squeeze out leading and trailing spaces $datemin =~ s/^\s+//; $datemin =~ s/\s+$//; $timemin =~ s/^\s+//; $timemin =~ s/\s+$//; $datemax =~ s/^\s+//; $datemax =~ s/\s+$//; $timemax =~ s/^\s+//; $timemax =~ s/\s+$//; print "beg: $datemin end: $datemax\n"; print "beg: $timemin end: $timemax\n"; print "Matches\n-------\n"; open(FILE, "/dave/MVPTEST/mvpdoc"); while (<FILE>) { chomp; if ($_ =~ /(\d{4})\s(\d{5})\s(\d{3})\s(\d{2})\s(\d{2}\/\d{ +2}\/\d{2})\s(\d{2}\:\d{2}\:\d{2})/) { if (($5 ge $datemin) && ($5 le $datemax) && ($6 ge $ti +memin) && ($6 le $timemax)) { print "$_\n"; } } } }

First yeah I know it was long and second I don't know how good my indenting is for the code. Usually I just post it in block form. Anyway you saw the hash in the very beginning called %TOC and the values of field 15 are defined. Well Duh you guys know that. Anywho here is an example of the data I'm going through.

4478 00300 064 01 01/11/19 00:00:46 03 00000092a71228a9 255 01 00:00:3 +0 01 00 00 00 DID 0000000000000000 000 0000000000000000 0000000000000 +000 0000000000000000 000 61

Now as it stands the script prints the line off as is above but I want to integrate the value of %TOC into the printed off line. The value for this line for field 15 being DID is "Digit Feed Recieved" I want that printed off in the line like the example below.

4478 00300 064 01 01/11/19 00:00:46 03 00000092a71228a9 255 01 00:00:30 01 00 00 00 (Digit Feed Recieved) 0000000000000000 000 0000000000000000 0000000000000000 0000000000000000 000 61
I can do single lines like something that was like this
dog 001 cat 002

Yeah I can match and print single lines but I never had to print off something that was internal to a line. I can do the following to get hash values printed.

if ($var =~ /dog\s(\d+)$/) { print "$TOC{$1}\n";
How would I go about getting what I need though.
if ($_ =~ /(\d{4})\s(\d{5})\s(\d{3})\s(\d{2})\s(\d{2}\/\d{2}\/\d{2})\s +(\d{2}\:\d{2}\:\d{2})\s(\d{3})\s(\d{2})\s(\S+)\s(\d{2})\s(\d{2})\s(\d +{2})\s(\d{2})\s(\w{3})$/) { print "$1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $TOC{$15)";
I think the above would work but I can't test it because for some reason (Which I don't know) The script will read fields like $5 for a match but it won't print them. So if I said
print "$1, $2";

The script won't do it. It will only print off my results using "print $_"; and I've used the $field vars before to get stuff to print but I don't get why this stuff won't.


I kinda know how to do it but I more or less confused myself between a rock and a confused spot. Please help me clear the fog up a little,

All help will be sincerely appreciated. Like I said though I think my indenting sucks.

The Brassmon_k

Edited 2001-01-02 by Ovid

Comment on Is it Possible to match contents in hash via a Regex?
Select or Download Code
Re: Is it Possible to match contents in hash via a Regex?
by brassmon_k (Sexton) on Jan 02, 2002 at 23:07 UTC
    This is the Brassmon_k,

    Sorry I forgot stuff like STDIN and FILE and well the shitty html HTMLIFIED parts of my script. Really Sorry. I don't know why though I put the damn pre HTML tags in for code. Oh well this is just so ya know.
(duplicate) Re: Is it Possible to match contents in hash via a Regex?
by dragonchild (Archbishop) on Jan 02, 2002 at 23:11 UTC
    What's wrong with:
    my $val = $15; print $TOC{$val};
    Also, don't use <&pre> ... use <code>

    ------
    We are the carpenters and bricklayers of the Information Age.

    Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

Re: Is it Possible to match contents in hash via a Regex?
by andye (Curate) on Jan 02, 2002 at 23:14 UTC
    I have to say I'm not 100% clear on your code ('cos I haven't read anything of it except the nasty big regexp :) but one suggestion does occur to me.

    The fields are separated by spaces, right, so why not just split into an array, then you'll be able to get at the array element you want. Something like this:

    my @flds = split / /; $flds[14] = $TOC{$flds[14]}; print "@flds" ;#this is quoted so it's printed with a space between ea +ch field
    hth,
    andy.
Re: Is it Possible to match contents in hash via a Regex?
by brassmon_k (Sexton) on Jan 02, 2002 at 23:40 UTC
    Okay sorry monks I had like a massive black hole brain lapse. All I do is just use a stupid array split on / / single space. I've done this B4 it's just been a while.

    Thanks!
Re: Is it Possible to match contents in hash via a Regex?
by dmmiller2k (Chaplain) on Jan 02, 2002 at 23:48 UTC

    </S>Update: withdrawn. Use split().

    Attempting to zero in on the problem you're having, it seems you are having trouble printing the match variables, $1, $2, .., $15. Perhaps another way of determining what matched might be in order (I've taken the liberty of changing your regex slightly using /x, for readibility):

    my @match_flds = /(\d{4}) \s (\d{5}) \s (\d{3}) \s (\d{2}) \s (\d{2} \/ \d{2} \/ \d{2}) \s (\d{2} \: \d{2} \: \d{2}) \s (\d{3}) \s (\d{2}) \s (\S+) \s (\d{2}) \s (\d{2}) \s (\d{2}) \s (\d{2}) \s (\w{3}) $ /x ; if (@match_flds) { # now indexes are 1-off from the corresponding numbered # regex vars: e.g., $match_flds[0] is $1, $match_flds[1] is $2, etc. # remap the 15th field using your hash $match_flds[14] = $TOC{ $match_flds[14] }; # print them print join( ' ', @match_flds ), "\n"; }

    dmm

    You can give a man a fish and feed him for a day ...
    Or, you can
    teach him to fish and feed him for a lifetime
      Okay everyone here is the finished code sorry it took so long had to test it on 2 other systems besides mine and some slight alterations were needed and the script had to be dressed up a little. I could make it even fancier (That's fun to do once you have the darn thing working!) but the users can have fun with it anyway.
      #!/usr/bin/perl -w #SMDR Record Script use strict; my $datemin; my $datemax; my $timemin; my $timemax; my $choice; my $msisdn; my $range; my $rangex; my $SIG; my %TOC; my %DC; my %PAC; %TOC = ( 'DID' => "Digit Feed Recieved", 'ETE' => "No digit feed/calle +r enters mailbox number", 'ODL' => "Outidal Delivery", 'ODN' => "Outdial Notification", 'DEP' => "Deposit Only", 'RET' => "Re +trieval Only", 'SMD' => "SMDI serially integrated trunk", 'PAG' => "Page delivery", 'ISI' => "Infoserv Recording", 'TAS' => "TAS + Call", 'TTT' => "Trunk to trunk transfer", 'PBX' => "PBX type transfer", 'CMC' => "Constant Touch", 'CMO' => "Con +stant Touch Outdial notification" ); %DC = ( '00' => "Timeout waiting for command", '01' => "Hang up or log + off", '02' => "DTMF 're-id' entered", '03' => "DTMF 'operator revert' entered", '04' => "DTMF 'call transfer +' entered", '05' => "Successful Outdial", '06' => "No Answer/busy outdial", '07' => "Not Implemented", '08' => " +Hardware or System problem", '09' => "Call terminated by system manager", '10' => "Too many subscri +ber errors", '11' => "Unidentified caller sent urgent message", '12' => "Outdial page fails", '13' => "Outdial page success", '14' => +"Leave system from trunk to trunk transfer", '15' => "Not Implemented", '16' => "Fax Transmission Fails", '17' => " +Subscriber sent Constant Touch caller to voice mail" ); %PAC = ( '00' => "Answer and play greeting", '01' => "Entered mailbox +number and left message", '02' => "Entered user name and left message +", '03' => "Entered mailbox number/password for access", '04' => "Not Imp +lemented", '05' => "Not Implemented", '06' => "Outdial to deliver message", '07' => "Outdial for message Not +ification", '08' => "Invalid mailbox number or name", '09' => "Invalid Security Code", '10' => "System problem prevented acc +ess", '11' => "Outdial Page", '12' => "Called, left a message and callback page", '13' => "Called an +d left Page" ); print "Your Options Are:\n"; print "\n"; print "Search by Start Date = 'd'\n"; print "Search by Start Time = 't'\n"; print "Search by VM Mailbox Number = 'v'\n"; print "Search by Start Date & Time = 'b'\n"; print "Quit Search Utility? = 'q'\n"; print "\n"; do { print "Select Your Option:> (d, t, v, b, q)"; #Choose a letter chomp($choice = <STDIN>); } until ($choice =~ /^[DdTtVvBbQq]/); if ($choice =~ /^[Dd]/) { print "Enter Date in Form:(01/11/19-01/11/22)\n"; $range = <STDIN>; ($datemin, $datemax) = split /-/, $range; #Squeeze out leading and trailing spaces $datemin =~ s/^\s+//; $datemin =~ s/\s+$//; $datemax =~ s/^\s+//; $datemax =~ s/\s+$//; print "Begin Date: $datemin-End Date: $datemax\n"; print "Matches\n-------\n"; open(FILE, "/home/dhagens/MVP.dump.capture.file"); while (<FILE>) { my @matched = /(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d{2}\/\d{2}\/\d{ +2})\s(\d{2}\:\d{2}\:\d{2})\s(\d+)\s(\S+)\s(\d+)\s(\d+)\s(\d{2}\:\d{2} +\:\d{2})\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\w+)\s(\d+)\s(\d+)\s(\d+)\s(\d ++)\s(\d+)\s(\d+)\s(\d+)\s(\S+)/; if (@matched) { $matched[1] = "*System ID String($matched[1])*"; $matched[5] = "*Call Start Time:($matched[5])*"; $matched[6] = "*Primary Activity Code:($PAC{$matched[6]})*" +; $matched[7] = "*Mailbox number of sender or subscriber:($ma +tched[7])*"; $matched[9] = "*Disconnect Code:($DC{$matched[9]})*"; $matched[10] = "*Elapsed Time of Call:($matched[10])*"; $matched[11] = "*Number of Messages Received:($matched[11]) +*"; $matched[12] = "*Number of Messages Sent:($matched[12])*"; $matched[15] = "*Type of Call:($TOC{$matched[15]})*"; if (($matched[4] ge $datemin) && ($matched[4] le $datemax)) + { $matched[4] = "*Start Date of Call:($matched[4])*"; print join( ' ', @matched ), "\n\n"; } } } } if ($choice =~ /^[Tt]/) { print "Enter Time in Form:(00:00:40-00:00:50)\n"; $rangex = <STDIN>; ($timemin, $timemax) = split /-/, $rangex; # Squeeze out leading and trailing spaces $timemin =~ s/^\s+//; $timemin =~ s/\s+$//; $timemax =~ s/^\s+//; $timemax =~ s/\s+$//; print "Begin Time: $timemin-End Time: $timemax\n"; print "Matches\n-------\n"; open(FILE, "/home/dhagens/MVP.dump.capture.file"); while (<FILE>) { my @matched = /(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d{2}\/\d{2}\/\d{2} +)\s(\d{2}\:\d{2}\:\d{2})\s(\d+)\s(\S+)\s(\d+)\s(\d+)\s(\d{2}\:\d{2}\: +\d{2})\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\w+)\s(\d+)\s(\d+)\s(\d+)\s(\d+) +\s(\d+)\s(\d+)\s(\d+)\s(\S+)/; if (@matched) { $matched[1] = "*System ID String($matched[1])*"; $matched[4] = "*Start Date of Call:($matched[4])*"; $matched[6] = "*Primary Activity Code:($PAC{$matched[6]})*"; $matched[7] = "*Mailbox number of sender or subscriber:($matc +hed[7])*"; $matched[9] = "*Disconnect Code:($DC{$matched[9]})*"; $matched[10] = "*Elapsed Time of Call:($matched[10])*"; $matched[11] = "*Number of Messages Received:($matched[11])*" +; $matched[12] = "*Number of Messages Sent:($matched[12])*"; $matched[15] = "*Type of Call:($TOC{$matched[15]})*"; if (($matched[5] ge $timemin) && ($matched[5] le $timemax)) { $matched[5] = "*Call Start Time:($matched[5])*"; print join( ' ', @matched ), "\n\n"; } } } } elsif ($choice =~ /^[Vv]/) { print "Enter VM Number in Form:(92a7a77248)zeros will be a's\n"; chomp($msisdn = <STDIN>); print "Matches\n-------\n"; open(FILE, "/home/dhagens/MVP.dump.capture.file"); while (<FILE>) { my @matched = /(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d{2}\/\d{2}\/\d{2} +)\s(\d{2}\:\d{2}\:\d{2})\s(\d+)\s(\S+)\s(\d+)\s(\d+)\s(\d{2}\:\d{2}\: +\d{2})\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\w+)\s(\d+)\s(\d+)\s(\d+)\s(\d+) +\s(\d+)\s(\d+)\s(\d+)\s(\S+)/; if (@matched) { $matched[1] = "*System ID String($matched[1])*"; $matched[4] = "*Start Date of Call:($matched[4])*"; $matched[5] = "*Call Start Time:($matched[5])*"; $matched[6] = "*Primary Activity Code:($PAC{$matched[6]})*" +; $matched[9] = "*Disconnect Code:($DC{$matched[9]})*"; $matched[10] = "*Elapsed Time of Call:($matched[10])*"; $matched[11] = "*Number of Messages Received:($matched[11]) +*"; $matched[12] = "*Number of Messages Sent:($matched[12])*"; $matched[15] = "*Type of Call:($TOC{$matched[15]})*"; if ($matched[7] =~ $msisdn) { $matched[7] = "*Mailbox number of sender or subscriber:($ +matched[7])*"; print join( ' ', @matched ), "\n\n"; } } } } elsif ($choice =~ /^[Bb]/) { print "Enter Date in Form:(01/11/19-01/11/22)\n"; $range = <STDIN>; print "Enter Time in Form:(00:00:40-00:00:50)\n"; $rangex = <STDIN>; # Break up the range ($datemin, $datemax) = split /-/, $range; ($timemin, $timemax) = split /-/, $rangex; # Squeeze out leading and trailing spaces $datemin =~ s/^\s+//; $datemin =~ s/\s+$//; $timemin =~ s/^\s+//; $timemin =~ s/\s+$//; $datemax =~ s/^\s+//; $datemax =~ s/\s+$//; $timemax =~ s/^\s+//; $timemax =~ s/\s+$//; print "Begin Date: $datemin-End Date: $datemax\n"; print "Begin Time: $timemin-End Time: $timemax\n"; print "Matches\n-------\n"; open(FILE, "/home/dhagens/MVP.dump.capture.file"); while (<FILE>) { my @matched = /(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\d{2}\/\d{2}\/\d{2} +)\s(\d{2}\:\d{2}\:\d{2})\s(\d+)\s(\S+)\s(\d+)\s(\d+)\s(\d{2}\:\d{2}\: +\d{2})\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\w+)\s(\d+)\s(\d+)\s(\d+)\s(\d+) +\s(\d+)\s(\d+)\s(\d+)\s(\S+)/; if (@matched) { $matched[1] = "*System ID String($matched[1])*"; $matched[6] = "*Primary Activity Code:($PAC{$matched[6]})*"; $matched[9] = "*Disconnect Code:($DC{$matched[9]})*"; $matched[10] = "*Elapsed Time of Call:($matched[10])*"; $matched[11] = "*Number of Messages Received:($matched[11])*" +; $matched[12] = "*Number of Messages Sent:($matched[12])*"; $matched[15] = "*Type of Call:($TOC{$matched[15]})*"; if (($matched[4] ge $datemin) && ($matched[4] le $datemax) && + ($matched[5] ge $timemin) && ($matched[5] le $timemax)) { $matched[4] = "*Start Date of Call:($matched[4])*"; $matched[5] = "*Call Start Time:($matched[5])*"; print join( ' ', @matched ), "\n\n"; } } } } elsif ($choice =~ /^[Qq]/) { $SIG{INT}; }
      And there it is! What the code does in a nutshell is just go through a text file and search by date or time or both or just a number. Well thakyou Monks it's been a pleasure. Now I go off to College.

      The Brassmon_k
Re: Is it Possible to match contents in hash via a Regex?
by brassmon_k (Sexton) on Jan 03, 2002 at 00:22 UTC
    Cool!
    I didn't know that you could put a regex into an array! That will make my script a lot cleaner...THANKS! Yeah, I can't believe I forgot that...
    @fld = split / /; if ($_ =~ "regex/); print "$1 $2, etc";
    THANKS MONKS!

    The Brassmon_k

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://135759]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (9)
As of 2014-10-23 17:55 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (126 votes), past polls