in reply to Match with line without a word

Yes , I already worked it out with 2 regex. I wanted to know if there is a more efficient way of doing it with one regex .

Replies are listed 'Best First'.
Re^2: Match with line without a word
by moritz (Cardinal) on Aug 07, 2009 at 07:49 UTC
    There is a way with one regex, but I don't think it will be much more efficient. Untested: /Exception : (?!CEX)/.

    See perlre for details on the look-ahead group

      use strict; use warnings; use Benchmark; my @strings = qw(exception:tex exception:mex asdf); Benchmark::cmpthese( -5, { 'one' => sub { my @filtered = grep { /exception:(?!tex)/} @strings +; }, 'two' => sub { my @filtered = grep { /exception/ && !/tex/ } @stri +ngs; }, }); __END__ Rate one two one 175458/s -- -15% two 207611/s 18% --

      update: The filter expressions are different. The second one does not care whether tex is before of after exception and doesn't require a ':' after 'exception'. I have stumbled on a patch of my ignorance trying to make the second match the same strings as the first. The best I have so far is:

      use strict; use warnings; use Benchmark; my @strings = qw(exception:tex exception:mex asdf tex:exception:mex); Benchmark::cmpthese( -5, { 'one' => sub { my @filtered = grep { /exception:(?!tex)/} @strings +; }, 'two' => sub { my @filtered = grep { /exception/ && !/tex/ } @stri +ngs; }, 'three' => sub { my @filtered = grep { pos = 0; /exception:/g && ! +/\Gtex/ } @strings; }, }); __END__ Rate three one two three 99554/s -- -18% -38% one 121692/s 22% -- -24% two 161067/s 62% 32% --

      update: see also strange behavior of grep with global match [resolved]. Adding "pos = 0" is necessary to clear pos between iterations but it would not be necessary if there were only a single iteration. This makes it difficult to compare the efficiency of "/exception/g && !/\Gtex/".

Re^2: Match with line without a word
by Marshall (Canon) on Aug 07, 2009 at 08:36 UTC
    There are a number of ways to do this. Easy way is with cascading "greps", like in my first example. Regex is wonderful at "or" but the "and" kind of thing can be complex in the syntax.

    I would suggest one of the below formulations. Tweak to suit your needs.

    oops, my brain is really out to lunch today...sorry.see update

    #!/usr/bin/perl -w use strict; my @input = ("Exception : CEX", "Exception : TEX", "abc def ljj"); print grep{/TEX/} grep{/^\s*Exception/}@input; print "\n"; print grep{/Exception/ && /TEX/}@input; print "\n"; print grep{/^\s*Exception.*? TEX/}@input; __END__ prints: Exception : TEX Exception : TEX Exception : TEX
    #!/usr/bin/perl -w use strict; my @input = ("Exception : CEX", "Exception : TEX", "abc def ljj"); print grep{!/CEX/}grep{/^\s*Exception/}@input; print "\n"; print grep{/Exception/ && !/CEX/}@input; print "\n"; __END__ prints: Exception : TEX Exception : TEX
    I wouldn't get overly concerned about performance unless this code is going to be executed lots of times. Clarity should be the first priority.
      Thanks a lot . I think this grep usage would do good , than nested regex .