tags:

views:

106

answers:

2

I am trying to write a regex to match the nth match. As I am new to regex please help me in solving this.

Input:

DECLARE numerator NUMBER; BEGIN SELECT x, y INTO numerator, denominator FROM result_table, secondTable WHERE sample_id = 8; delete from xyz where id=17;

Match first WHERE or match second WHERE.

Also please suggest me some good link towards:

  1. Greedy and non-greedy approach.
  2. Nested regular expression.

Thanks in advance.

+1  A: 

You did not specify a language. I am assuming that you are using some form of a dynamic scripting language (Perl, C#, Ruby, Python, etc) where the regex concepts are very similar. I will show you how to do this in Perl and whatever language you are using should be similar.

With Perl, you can do global matching of a regex pattern and return a list to operate on. With this list, you can address the nth match by using array offsets into the returned list.

Consider:

#!/usr/bin/perl

use strict; use warnings;

# use a block of text; in this case "Grimms' Tales from Gutenburg
GetGrimmFairyTail() unless -e '2591.txt';

my (@m1,@m2);
my $i=1;
open (my $grimms,'<','2591.txt') or die $!;
undef $/; #'slurp' mode
my $tail=<$grimms>;

# How many 'cats' in Grimms' Tails?
my $regex=qr/(^.*?\bcat\b.*$)/mi;

@m1=($tail=~(/$regex/g)); 
print   "\n",
        scalar @m1, " global matches\n";

print   "first match is:\n$m1[0]\n",
        "second is:\n$m1[1]\n",
        "last is:\n$m1[-1]\n", 
        "second to last is:\n$m1[-2]\n\n\n";

#How many dogs?
$regex=qr/(^.*?\bdog\b.*$)/mi;      
foreach my $line (split (/\n/,$tail))  {
     while ($line=~/$regex/g) {
        push @m2, [ "Line $i", $1 ];
     }   
     $i++;
 }      

print scalar @m2, " foreach loop matches\n";        
print   "first match with line number:\n$m2[0][0]: $m2[0][1]\n",
        "second is:\n$m2[1][0]: $m2[1][1]\n",
        "last is:\n$m2[-1][0]: $m2[-1][1]\n", 
        "second to last is:\n$m2[-2][0]: $m2[-2][1]\n\n";       

print "The end!\n\n";

sub GetGrimmFairyTail {
    use Net::ftp;
    use File::Spec;
    print   "\n",
            "Getting \"Grimms' Fairy Tales\" from ", 
            "University of North Carolina, Chapel Hill....\n\n";
    my $host='ibiblio.org';
    my $lf;
    my $ftp=Net::FTP->new($host,DEBUG=>0) 
        or die "Cannot connect to $host: $@";
    $ftp->login("anonymous",'-anonymous@')
          or die "Cannot login ", $ftp->message;  
    my $fn=$lf=$ftp->get("/pub/docs/books/gutenberg/2/5/9/2591/2591.txt")
          or die "get failed ", $ftp->message;    
    my $size= -s $fn;
    my $abspath=File::Spec->rel2abs($fn);
    open (my $fh, '<', $fn) or die "can't open downloaded file: $!";
    my $line_count=0;
    my $rs=$/;
    $line_count++ while <$fh>;
    $/=$rs;
    print   "Success!\n",
            "$size bytes containing $line_count lines downloaded into file:\n",
            "$abspath\n\n" if -e $abspath;
    $ftp->quit;
}

The return is:

87 global matches
first match is:
     CAT AND MOUSE IN PARTNERSHIP
second is:
     THE FOX AND THE CAT
last is:
king got to the bottom, he ordered Cat-skin to be called once more, and
second to last is:
Cat-skin,' said the cook; 'for you always put something into your soup,


41 foreach loop matches
first match with line number:
Line 57:      THE DOG AND THE SPARROW
second is:
Line 665: After he had travelled a little way, he spied a dog lying by the
last is:
Line 9078: crevice of the tree, and the little fellow was jumping about like a dog
second to last is:
Line 8561: pursue it; but hardly had the dog run two steps when it stood before a

The end!
drewk
+1  A: 

Regarding your second Question ie.,good links for Regular Expression:-

http://www.regular-expressions.info/

see: http://stackoverflow.com/questions/4736/learning-regular-expressions ,

you will get good suggestions regarding books, links, tools for Regular Expression etc.

Nikhil Jain