Parsing a string

Here is an example of a string I am trying to match:

SidDbData:A01|1|000588|01|01|S SID|A01|||164.103.137.43|3690|164.103.137.46|1098981768 APS|sapa01ci_A01_90|UNIX|SunOS|3290|3390 APS|sapapp25_A01_02|UNIX|SunOS|3202|3302 CYC|20041101|0014|1099320171|083744|1099319864 ABERR|0|0 ARFC|0|0 BDC|0|0 CCMS_ALERTS|0|0 ENQUEU|1|1 0014|083240|083744|0|85|80| ER_CON|0|0 IDOC_N|0|0 JOB|0|0 LOCKS|0|0 OLD_PROD|4|4 WA|DB-Maintain for Orac|0|4.3.00| GR|S.L. Reporter|0|4.3.00| MA|Manager|0|4.3.00| TR|Trak|0|4.3.00| PRINT|0|0 QRFC|0|0 SPOOL|0|0 SPOOL_SIZE|1|1 2915| TR_REQ|0|0 SID_PORTS|3|3 Msgs|sapa01ci|sapmsA01| Msgs_Http|sapa01ci|8190| Msgs_Https|sapa01ci||

I am picking out the "S SID" and I want to look for ER_CON| and the digit after it, IDOC_N| and the digit after it and JOB| and the digit after it. This is what I have so far and it works with the above trap:

my($sid, @test) = $string =~ /.* SID\|(.*?)\|.* ER_CON\|(\d?)\|.* IDOC_N\|(\d?)\|.* JOB\|(\d?)\|.*/;

print "\nSID equals $sid\n";
print "\nER_CON errors = ", $test[0], "\n";
print "IDOC_N errors = ", $test[1], "\n";
print "JOB errors = ", $test[2], "\n";

The problem is that SOMETIMES, either ER_CON, IDOC_N or JOB will either be in a different order or (most likely) not exist at all. If that happens, I still want to print out the one that DOES exist and it's value. Is there any way to do that? Also, I would appreciate any comments / suggestions one the way I am matching what I have so far.

Thanks!
holein5

LVL 1
David AldridgeAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

David AldridgeAuthor Commented:
I made a SLIGHT mistake in my regex.. here's what I have:

my($sid, @test) = $string =~ /.*S SID\|(.*?)\|.* ER_CON\|(\d?)\|.* IDOC_N\|(\d?)\|.* JOB\|(\d?)\|.*/
0
manav_mathurCommented:
What you can do is extract each of them seperately

if ($string =~ /.*S SID\|(.*?)\|/) {
print "$1" ;
}
else {
print "S SIDNot found" ;
}

and so on and so forth for each of your ER_CON, IDOC_N and JOB fields.

This will take care of any spurious order in which they may be occuring in your string and will aslo take care if they are not present entirely in the string

Manav
0
manav_mathurCommented:
Try this,

#!/usr/local/bin/perl
use strict;
use warnings;
my $string="SidDbData:A01|1|000588|01|01|S SID|A01|164.103.137.43|3690|164.103.137.46|1098981768 APS|sapa01ci_A01_90|UNIX|SunOS|3290|3390 APS|sapapp25_A01_02|UNIX|SunOS|3202|3302 CYC|20041101|0014|1099320171|083744|1099319864 ABERR|0|0 ARFC|0|0 BDC|0|0 CCMS_ALERTS|0|0 ENQUEU|1|1 0014|083240|083744|0|85|80| ER_CON|0|0 IDOC_N|0|0 JOB|0|0 LOCKS|0|0 OLD_PROD|4|4 WA|DB-Maintain for Orac|0|4.3.00| GR|S.L. Reporter|0|4.3.00| MA|Manager|0|4.3.00| TR|Trak|0|4.3.00| PRINT|0|0 QRFC|0|0 SPOOL|0|0 SPOOL_SIZE|1|1 2915| TR_REQ|0|0 SID_PORTS|3|3 Msgs|sapa01ci|sapmsA01| Msgs_Http|sapa01ci|8190| Msgs_Https|sapa01ci||" ;
if ($string =~ /.*S SID\|(.*?)\|/) {
print "S SID : $1\n" ;
}
else {
print "S SID : Not found\n" ;
}
if ($string =~ /ER_CON\|(\d?)\|/) {
print "ER_CON : $1\n" ;
}
else {
print "ER_CON : Not found\n" ;
}
if ($string =~ /IDOC_N\|(\d?)\|/) {
print "IDOC_N : $1\n" ;
}
else {
print "IDOC_N : Not found\n" ;
}
if ($string =~ /JOB\|(\d?)\|/) {
print "JOB : $1\n" ;
}
else {
print "JOB : Not found\n" ;
}


Cheers
Manav
0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

David AldridgeAuthor Commented:
Ok, so does this look like the best way? It works, but it just seems inefficient.

#!/perl

use strict;
use warnings;

my $string = shift;
if($string =~ /.*S SID\|(.*?)\|.*/) {
    print "\nSID equals $1\n";
}
if($string =~ /.*ER_CON\|(\d?)\|.*/) {
    print "ER_CON errors = $1\n";
}
if($string =~ /.*IDOC_N\|(\d?)\|.*/) {
    print "IDOC_N errors = $1\n";
}
if($string =~ /.*JOB\|(\d?)\|.*/) {
    print "JOB errors = $1\n";
}
0
David AldridgeAuthor Commented:
I don't need an error message if it's not found.. sorry about that.
0
manav_mathurCommented:
Holein5,

If you take a modular approach to your problem, then each reg-ex becomes an independent string. Thats because, under the gven constraints, each of S SID, IDOC_N have no relationship with each other. They can occur anywhere independently of each other. In your reg-ex, even if one pattern doesnt match, the entire reg-ex fails.

This contradicts the approach that we designed bfore. Hence, independent reg-ex(s) are needed for this.

Cheers,
Manav
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
David AldridgeAuthor Commented:
Ok, thank you very much for the help! Looks like this is the one I'll be using.

holein5
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.