Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

In the following example I'm trying to exclude any form of Exception Handler but need to find just the word Exception.
Here is what I came up with but it seems to find all Exceptions
use strict; use warnings; while(<DATA>) { chomp; if ( /((?!Exception\s+Handler|ExceptionHandler).)*Exception/i ) { print "FOUND : $_\n"; } } __DATA__ Line1: Extension: name="Exception Handler" point="ClientDebugGroupExt +ension" className="com.foo.bar.pluginfwk.extensions.DefaultDebugGroup +Extension" instance=Not created params:( packages="com.foo.bar.common +.ExceptionHandler;" level="Verbose" description="User interface unhan +dled exception handler" ) Line2: java.net.SocketException: Software caused connection abort: rec +v failed Line3: com.mysql.jdbc.CommunicationsException Line4: MESSAGE: Communications link failure due to underlying exceptio +n:
I would expect this script to find lines 2,3,4
Any idea what I'm missing?
Thanks

Replies are listed 'Best First'.
Re: regex help needed
by Eliya (Vicar) on Mar 28, 2011 at 18:13 UTC
    if ( /exception(?!\s*handler)/i ) {

    which means: exception, not followed by \s*handler.

Re: regex help needed
by dasgar (Priest) on Mar 28, 2011 at 18:20 UTC

    Here's a two step approach to accomplish the task.

    Change your if statement to be:

    if ((/Exception/i) && !(/Exception Handler/i)) { print "FOUND : $_\n"; }

    Might not be elegant, but it gets the job done. If you prefer to use a singe regex, I'd probably go with what Eliya posted.

      And I’d go with what you did ... an if statement ... purely on “the next-time principle.”   The one and only thing you can be sure of is change, so make the code as easy as possible to change next-time.   A “clever” regex might be difficult to change – and soon enough a change might well will come along soon for which it is impossible.   It’s really only a matter of time.   Conditional logic, which does not place the full responsibility upon a single regex but merely obliges it “to get us into the right neighborhood,” will be much more forgiving of change in the long run.

Re: regex help needed
by samarzone (Pilgrim) on Mar 29, 2011 at 07:57 UTC

    You got the solutions by Eliya and dasgar. Here is the answer of

    Any idea what I'm missing?

    The dot (.) after the first closing bracket is creating problem. Remove it and the asterisk as well.

    I was trying to explain the regex but I found it quite difficult for me to write it in simple language. :)

    You can try to find out where and why the pattern matched by printing $1 or adding multiple capturing brackets before or after the negative look ahead pattern and then printing the corresponding matches

    --
    Regards
    - Samar
Re: regex help needed
by Anonymous Monk on Mar 28, 2011 at 18:12 UTC
    I modified the regex to look like this:
    if ( /((?!Exception\s+Handler|ExceptionHandler)).*Exception:|\w+Ex +ception/i ) { print "FOUND : $_\n"; }
    And it seems to work, but I'm not sure it's entirely correct.