代码之家  ›  专栏  ›  技术社区  ›  vrbilgi

regex:查找第n个匹配项

  •  1
  • vrbilgi  · 技术社区  · 16 年前

    我想写一个regex来匹配第n个匹配。因为我是新来的雷杰克斯,请帮助我 解决这个问题。

    输入:

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

    先在哪里匹配,再在哪里匹配。

    另外,请建议我一些好的链接:

    1. 贪婪和非贪婪的方法。
    2. 嵌套正则表达式。

    事先谢谢。

    2 回复  |  直到 16 年前
        1
  •  1
  •   Community Mohan Dere    9 年前

    关于第二个问题,即,正则表达式的良好链接:

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

    见: Learning Regular Expressions ,

    你会得到关于书籍、链接、正则表达式工具等的好建议。

        2
  •  4
  •   dawg    16 年前

    您没有指定语言。我假设您正在使用某种形式的动态脚本语言(perl、c_、ruby、python等),其中regex概念非常相似。我将向您展示如何用Perl来实现这一点,您使用的任何语言都应该类似。

    使用Perl,可以对regex模式进行全局匹配,并返回一个要操作的列表。使用此列表,可以通过在返回的列表中使用数组偏移量来处理第n个匹配项。

    考虑:

    #!/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;
    }
    

    回报是:

    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!