RE: Regex parsing question

2003-07-11 Thread Pandey Rajeev-A19514
Hi Rob,

Thanks ! That was helpful. 
Do we have a lex and Yacc equivalent in Perl ?

I am writing an automation tool based on Client and server for Cisco devices.
I am doing the testcase parsing in Lex and Yacc (flex and bison) to create the parser 
tree and then I user the server written in Perl to do all the regex jobs. ( More 
details are irrelevant in this context).

In my test case file I wanted to specify a regular expression equivalent (a one liner) 
that can be generic enough for any kind of pattern matching. 

For eg. If my buffer contains something like this

Vlan1  10.20.0.53  YES NVRAM  upup  
Vlan2  10.21.0.1   YES NVRAM  upup  
Vlan5  10.20.0.17  YES NVRAM  upup  
Vlan6  10.3.4.1YES manual administratively down down
Vlan7  192.168.190.5   YES NVRAM  updown
Vlan8  10.21.4.129 YES NVRAM  updown 
*
and I want to list out all the A Vlan which is up/up then I write an regular exp as
(Not writing the actual syntax of my testcase file)
Vlan(\s|\d|\.|\w|)*up(\s|\d|\.|\w|)*up

and I get the result as
Vlan1  10.20.0.53  YES NVRAM  upup  
Vlan2  10.21.0.1   YES NVRAM  upup  
Vlan5  10.20.0.17  YES NVRAM  upup  

This was a simpler one..
But there are certain set of patterns which starts somwhere in one line, may have 
intermediate pattern in the middle lines and will end in another line. 

I just wanted a simple way of writing a oneliner regex for any kind of pattern 
matching such that I dont have to write any if-else code in perl.

I needed a generic one liner GENERIC-REGEX such that

if($buffer =~ /GENERIC-REGEX/) {
 print "My job is done";
}

Is it possible.. or  will I have to dig deeper in regex fundamentals.

Thanks for ur help.

Regards
Rajeev

-Original Message-
From: Rob Dixon [mailto:[EMAIL PROTECTED]
Sent: Friday, July 11, 2003 10:46 PM
To: [EMAIL PROTECTED]
Subject: Re: Regex parsing question


Rob Dixon wrote:
> Perl wrote:
> > I am attempting to parse a log file that looks something like:
> >
> > 759033281 TE18  constructor - add to MDBTable
> > EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> > 759033281 TE18  AddRef=2
> > EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> > 759033281 TE18  S-REXCH-MSG-07
> > 759033281 TE18  S-REXCH-MSG-06
> > 759033281 TE18  C-REXCH-MSG-07
> > 759033281 TE18  C-REXCH-MSG-06
> > 759033281 TE18  Vups_MailboxLogon done 0x0
> > 759033281 TE18  C-REXCH-MSG-06
> > 759033281 TE18  No timestamp for thread
> > 759033281 TE18  IMAPISession::OpenMsgStore  M
> > 109 Q  0
> >
> >
> > The only lines I am interested in are ones that have "PHARWOOD"
> > followed by a line that has "OpenMsgStore" in it.
> >
> > If I could explain this in English, I would want to say:
> >
> > "Search for an instance of "PHARWOOD" and once found print that
> > line. Then search for the very next instance of "OpenMsgStore"
> > that follows PHARWOOD (whether it be the next line or several
> > lines down) and print that."
> >
> >
> >
> > The code I have so far works but I don't understand how to change
> > my Regex filter to change from PHARWOOD to OpenMsgStore and back
> > again. Or is there a simpler method?
> >
> > Any help welcome,
> >
> > --Paul
> >
> >
> > ---
> >
> > $umlogs = "z\:";
> > opendir (DIR, "$umlogs") || die "Unable to open $umlogs
> > because:\n$!\n"; @dirs = readdir(DIR);
> > foreach $dir (@dirs) {
> > if ($dir =~/^V_DEBUG/i) {
> >
> >
> > open (LOGFILE, "$umlogs\\$dir") || die "unable to open $dir
> > because:\n$!\n";
> >
> > print "$umlogs\\$dir\n";
> > while () {
> > my @fields = split / /;
> >
> >
> > if (/PHARWOOD/) {
> >
> > print $_;
> >
> >
> > }
> > }
> > }
> >
> >
> > }
>
> This loop does what you ask
>
>   print if /PHARWOOD/ .. /OpenMsgStore/ while ;
>
> but if your input looks like
>
>
>   PHARWOOD
> :
>   PHARWOOD
> :
>   OpenMsgStore
>
> then it will print the whole sequence, not just those lines
> starting at the second 'PHARWOOD'. Is that what you want?
>

I'll get it right this time!

The loop needs to be

  while () {
print if /PHARWOOD/ ... /OpenMsgStore/;
  }

as you can't modify a statement with both an if .. and a while ..

Rob




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Regex parsing question

2003-07-11 Thread Rob Dixon
Rob Dixon wrote:
> Perl wrote:
> > I am attempting to parse a log file that looks something like:
> >
> > 759033281 TE18  constructor - add to MDBTable
> > EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> > 759033281 TE18  AddRef=2
> > EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> > 759033281 TE18  S-REXCH-MSG-07
> > 759033281 TE18  S-REXCH-MSG-06
> > 759033281 TE18  C-REXCH-MSG-07
> > 759033281 TE18  C-REXCH-MSG-06
> > 759033281 TE18  Vups_MailboxLogon done 0x0
> > 759033281 TE18  C-REXCH-MSG-06
> > 759033281 TE18  No timestamp for thread
> > 759033281 TE18  IMAPISession::OpenMsgStore  M
> > 109 Q  0
> >
> >
> > The only lines I am interested in are ones that have "PHARWOOD"
> > followed by a line that has "OpenMsgStore" in it.
> >
> > If I could explain this in English, I would want to say:
> >
> > "Search for an instance of "PHARWOOD" and once found print that
> > line. Then search for the very next instance of "OpenMsgStore"
> > that follows PHARWOOD (whether it be the next line or several
> > lines down) and print that."
> >
> >
> >
> > The code I have so far works but I don't understand how to change
> > my Regex filter to change from PHARWOOD to OpenMsgStore and back
> > again. Or is there a simpler method?
> >
> > Any help welcome,
> >
> > --Paul
> >
> >
> > ---
> >
> > $umlogs = "z\:";
> > opendir (DIR, "$umlogs") || die "Unable to open $umlogs
> > because:\n$!\n"; @dirs = readdir(DIR);
> > foreach $dir (@dirs) {
> > if ($dir =~/^V_DEBUG/i) {
> >
> >
> > open (LOGFILE, "$umlogs\\$dir") || die "unable to open $dir
> > because:\n$!\n";
> >
> > print "$umlogs\\$dir\n";
> > while () {
> > my @fields = split / /;
> >
> >
> > if (/PHARWOOD/) {
> >
> > print $_;
> >
> >
> > }
> > }
> > }
> >
> >
> > }
>
> This loop does what you ask
>
>   print if /PHARWOOD/ .. /OpenMsgStore/ while ;
>
> but if your input looks like
>
>
>   PHARWOOD
> :
>   PHARWOOD
> :
>   OpenMsgStore
>
> then it will print the whole sequence, not just those lines
> starting at the second 'PHARWOOD'. Is that what you want?
>

I'll get it right this time!

The loop needs to be

  while () {
print if /PHARWOOD/ ... /OpenMsgStore/;
  }

as you can't modify a statement with both an if .. and a while ..

Rob




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Regex parsing question

2003-07-11 Thread Rob Dixon
Perl wrote:
> I am attempting to parse a log file that looks something like:
>
> 759033281 TE18  constructor - add to MDBTable
> EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> 759033281 TE18  AddRef=2
> EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> 759033281 TE18  S-REXCH-MSG-07
> 759033281 TE18  S-REXCH-MSG-06
> 759033281 TE18  C-REXCH-MSG-07
> 759033281 TE18  C-REXCH-MSG-06
> 759033281 TE18  Vups_MailboxLogon done 0x0
> 759033281 TE18  C-REXCH-MSG-06
> 759033281 TE18  No timestamp for thread
> 759033281 TE18  IMAPISession::OpenMsgStore  M
> 109 Q  0
>
>
> The only lines I am interested in are ones that have "PHARWOOD"
> followed by a line that has "OpenMsgStore" in it.
>
> If I could explain this in English, I would want to say:
>
> "Search for an instance of "PHARWOOD" and once found print that
> line. Then search for the very next instance of "OpenMsgStore" that
> follows PHARWOOD (whether it be the next line or several lines
> down) and print that."
>
>
>
> The code I have so far works but I don't understand how to change my
> Regex filter to change from PHARWOOD to OpenMsgStore and back
> again. Or is there a simpler method?
>
> Any help welcome,
>
> --Paul
>
>
> ---
>
> $umlogs = "z\:";
> opendir (DIR, "$umlogs") || die "Unable to open $umlogs
> because:\n$!\n"; @dirs = readdir(DIR);
> foreach $dir (@dirs) {
> if ($dir =~/^V_DEBUG/i) {
>
>
> open (LOGFILE, "$umlogs\\$dir") || die "unable to open $dir
> because:\n$!\n";
>
> print "$umlogs\\$dir\n";
> while () {
> my @fields = split / /;
>
>
> if (/PHARWOOD/) {
>
> print $_;
>
>
> }
> }
> }
>
>
> }

This loop does what you ask

  print if /PHARWOOD/ .. /OpenMsgStore/ while ;

but if your input looks like


  PHARWOOD
:
  PHARWOOD
:
  OpenMsgStore

then it will print the whole sequence, not just those lines
starting at the second 'PHARWOOD'. Is that what you want?

Cheers,

Rob





-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Regex parsing question

2003-07-11 Thread Rob Dixon
Perl wrote:
> I am attempting to parse a log file that looks something like:
>
> 759033281 TE18  constructor - add to MDBTable
> EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> 759033281 TE18  AddRef=2
> EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> 759033281 TE18  S-REXCH-MSG-07
> 759033281 TE18  S-REXCH-MSG-06
> 759033281 TE18  C-REXCH-MSG-07
> 759033281 TE18  C-REXCH-MSG-06
> 759033281 TE18  Vups_MailboxLogon done 0x0
> 759033281 TE18  C-REXCH-MSG-06
> 759033281 TE18  No timestamp for thread
> 759033281 TE18  IMAPISession::OpenMsgStore  M
> 109 Q  0
>
>
> The only lines I am interested in are ones that have "PHARWOOD"
> followed by a line that has "OpenMsgStore" in it.
>
> If I could explain this in English, I would want to say:
>
> "Search for an instance of "PHARWOOD" and once found print that
> line. Then search for the very next instance of "OpenMsgStore" that
> follows PHARWOOD (whether it be the next line or several lines
> down) and print that."
>
>
>
> The code I have so far works but I don't understand how to change my
> Regex filter to change from PHARWOOD to OpenMsgStore and back
> again. Or is there a simpler method?
>
> Any help welcome,
>
> --Paul
>
>
> ---
>
> $umlogs = "z\:";
> opendir (DIR, "$umlogs") || die "Unable to open $umlogs
> because:\n$!\n"; @dirs = readdir(DIR);
> foreach $dir (@dirs) {
> if ($dir =~/^V_DEBUG/i) {
>
>
> open (LOGFILE, "$umlogs\\$dir") || die "unable to open $dir
> because:\n$!\n";
>
> print "$umlogs\\$dir\n";
> while () {
> my @fields = split / /;
>
>
> if (/PHARWOOD/) {
>
> print $_;
>
>
> }
> }
> }
>
>
> }

This loop does what you ask

  print if /PHARWOOD/ .. /OpenMsgStore/ while ;

but if your input looks like


  PHARWOOD
:
  PHARWOOD
:
  OpenMsgStore




-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Regex parsing question

2003-07-10 Thread John W. Krahn
Perl wrote:
> 
> I am attempting to parse a log file that looks something like:
> 
> 759033281 TE18  constructor - add to MDBTable
> EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> 759033281 TE18  AddRef=2
> EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> 759033281 TE18  S-REXCH-MSG-07
> 759033281 TE18  S-REXCH-MSG-06
> 759033281 TE18  C-REXCH-MSG-07
> 759033281 TE18  C-REXCH-MSG-06
> 759033281 TE18  Vups_MailboxLogon done 0x0
> 759033281 TE18  C-REXCH-MSG-06
> 759033281 TE18  No timestamp for thread
> 759033281 TE18  IMAPISession::OpenMsgStore  M109
> Q  0
> 
> The only lines I am interested in are ones that have "PHARWOOD" followed
> by a line that has "OpenMsgStore" in it.
> 
> If I could explain this in English, I would want to say:
> 
> "Search for an instance of "PHARWOOD" and once found print that line.
> Then search for the very next instance of "OpenMsgStore" that follows
> PHARWOOD (whether it be the next line or several lines down) and print
> that."
> 
> The code I have so far works but I don't understand how to change my
> Regex filter to change from PHARWOOD to OpenMsgStore and back again. Or
> is there a simpler method?

Something like this should work:

my $umlogs = 'z:';

local @ARGV = <$umlogs/*>;

my $found = 0;
while ( <> ) {
if ( /PHARWOOD/ ) {
print;
$found = 1;
}
if ( $found and /OpenMsgStore/ ) {
print;
$found = 0;
}
}

__END__


John
-- 
use Perl;
program
fulfillment

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Regex parsing question

2003-07-10 Thread Perl
I am attempting to parse a log file that looks something like:

759033281 TE18  constructor - add to MDBTable
EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
759033281 TE18  AddRef=2
EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
759033281 TE18  S-REXCH-MSG-07
759033281 TE18  S-REXCH-MSG-06
759033281 TE18  C-REXCH-MSG-07
759033281 TE18  C-REXCH-MSG-06
759033281 TE18  Vups_MailboxLogon done 0x0
759033281 TE18  C-REXCH-MSG-06
759033281 TE18  No timestamp for thread
759033281 TE18  IMAPISession::OpenMsgStore  M109
Q  0


The only lines I am interested in are ones that have "PHARWOOD" followed
by a line that has "OpenMsgStore" in it.

If I could explain this in English, I would want to say:

"Search for an instance of "PHARWOOD" and once found print that line.
Then search for the very next instance of "OpenMsgStore" that follows
PHARWOOD (whether it be the next line or several lines down) and print
that."



The code I have so far works but I don't understand how to change my
Regex filter to change from PHARWOOD to OpenMsgStore and back again. Or
is there a simpler method?

Any help welcome,

--Paul


---

$umlogs = "z\:";
opendir (DIR, "$umlogs") || die "Unable to open $umlogs because:\n$!\n";
@dirs = readdir(DIR);
foreach $dir (@dirs) {
if ($dir =~/^V_DEBUG/i) {


open (LOGFILE, "$umlogs\\$dir") || die "unable to open $dir
because:\n$!\n";

print "$umlogs\\$dir\n";
while () {
my @fields = split / /;


if (/PHARWOOD/) {

print $_;


}
}
}


}