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  up                    up      
Vlan2                      10.21.0.1       YES NVRAM  up                    up      
Vlan5                      10.20.0.17      YES NVRAM  up                    up      
Vlan6                      10.3.4.1        YES manual administratively down down    
Vlan7                      192.168.190.5   YES NVRAM  up                    down    
Vlan8                      10.21.4.129     YES NVRAM  up                    down     
*****************************************
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  up                    up      
Vlan2                      10.21.0.1       YES NVRAM  up                    up      
Vlan5                      10.20.0.17      YES NVRAM  up                    up      

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 <Vups_MsgStore> constructor - add to MDBTable
> > EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> > 759033281 TE18 <Vups_MsgStore> AddRef=2
> > EX:/O=MSGENG/OU=EUROPE/CN=RECIPIENTS/CN=PHARWOOD
> > 759033281 TE18 <MSM> S-REXCH-MSG-07
> > 759033281 TE18 <MSM> S-REXCH-MSG-06
> > 759033281 TE18 <MSM> C-REXCH-MSG-07
> > 759033281 TE18 <MSM> C-REXCH-MSG-06
> > 759033281 TE18 <VUPSMAPI> Vups_MailboxLogon done 0x0
> > 759033281 TE18 <MSM> C-REXCH-MSG-06
> > 759033281 TE18 <MSM> No timestamp for thread
> > 759033281 TE18 <MsgLog>     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 (<LOGFILE>) {
> > my @fields = split / /;
> >
> >
> > if (/PHARWOOD/) {
> >
> > print $_;
> >
> >
> > }
> > }
> > }
> >
> >
> > }
>
> This loop does what you ask
>
>   print if /PHARWOOD/ .. /OpenMsgStore/ while <LOGFILE>;
>
> 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 (<LOGFILE>) {
    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]

Reply via email to