3 Replies Latest reply on Jul 4, 2011 7:09 PM by John Hawkinson

    GREP Searches

    abssiddiq

      Hi


      I want to know what this exactly means in GREP and how it searches?


         1. Positive Lookbehind

         2. Negative Lookbehind

         3. Positive Lookahead

         4. Negative Lookahead


      Thanks

      Siddiq

        • 1. Re: GREP Searches
          Scott Falkner Level 5

          rtfd

          • 2. Re: GREP Searches
            Peter Spier Most Valuable Participant (Moderator)

            Lookahead/lookbehind are modifiers that tell your query that the saerch string is a match only if it is or is not (positive or negative) followed or preceeded, repectively, by some other text that you specify.

             

            Peter Kahrel has written an excellent primer on GREP in InDesign that is very inexpensive and availble from O'Reilly.

            • 3. Re: GREP Searches
              John Hawkinson Level 5

              rtfd

              Scott, this is unfair, since Adobe's documentation gives no good explanation for what these things mean.

               

              I personally like the perl documentation: http://perldoc.perl.org/perlre.html#Look-Around-Assertions:

               

              Look-Around Assertions   

              Look-around assertions are zero-width patterns which match a specific pattern without including it in $& . Positive assertions match when their subpattern matches, negative assertions match when their subpattern fails. Look-behind matches text up to the current match position, look-ahead matches text following the current match position.

              • (?=pattern)  

                A zero-width positive look-ahead assertion.  For example, /\w+(?=\t)/ matches a word followed by a tab, without including the tab in $& .

              • (?!pattern)  

                A zero-width negative look-ahead assertion.  For example /foo(?!bar)/ matches any occurrence of "foo" that isn't followed by "bar".  Note however that look-ahead and look-behind are NOT the same thing.  You cannot use this for look-behind.

                If you are looking for a "bar" that isn't preceded by a "foo", /(?!foo)bar/ will not do what you want.  That's because the (?!foo) is just saying that the next thing cannot be "foo"--and it's not, it's a "bar", so "foobar" will match.  Use look-behind instead (see below).

              • (?<=pattern) \K   

                A zero-width positive look-behind assertion.  For example, /(?<=\t)\w+/ matches a word that follows a tab, without including the tab in $& . Works only for fixed-width look-behind.

                There is a special form of this construct, called \K , which causes the regex engine to "keep" everything it had matched prior to the \K and not include it in $& . This effectively provides variable-length look-behind. The use of \K inside of another look-around assertion is allowed, but the behaviour is currently not well defined.

                For various reasons \K may be significantly more efficient than the equivalent (?<=...) construct, and it is especially useful in situations where you want to efficiently remove something following something else in a string. For instance

                1.   s/(foo)bar/$1/g;

                can be rewritten as the much more efficient

                1.   s/foo\Kbar//g;
              • (?<!pattern)  

                A zero-width negative look-behind assertion.  For example /(?<!bar)foo/ matches any occurrence of "foo" that does not follow "bar".  Works only for fixed-width look-behind.