Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

(dooberwah) I'm don't think that gives the same results

by dooberwah (Pilgrim)
on Feb 21, 2002 at 15:40 UTC ( [id://146773]=note: print w/replies, xml ) Need Help??


in reply to Re: Regular Expression Tweaking
in thread Regular Expression Tweaking

I don't think that that solution gives the same results.

From perlre:

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

Perhaps you mean to use the (?<!pattern) look behind assertion?

More From perlre:

(?<!pattern)
A zero-width negative lookbehind assertion. For example /(?<!bar)foo/ matches any occurrence of ``foo'' that isn't following ``bar''. Works only for fixed-width lookbehind.

-Ben Jacobs (dooberwah)
http://dooberwah.perlmonk.org
"one thing i can tell you is you got to be free"

Replies are listed 'Best First'.
Re: (dooberwah) I'm don't think that gives the same results
by blakem (Monsignor) on Feb 21, 2002 at 19:31 UTC
    Actually, lookbehind and lookahead seem to be the same when the assertion itself has zero-width... In the following code, looking ahead for the anchor produces the same results as looking behind for it.
    #!/usr/bin/perl -wT use strict; # Replace 'See' anywhere in the string $_ = "See spot run. See spot jump."; s/See/MATCH/g; print "'$_'\n"; # 'MATCH spot run. MATCH spot jump.' # Replace 'See' unless lookahead finds the anchor $_ = "See spot run. See spot jump."; s/(?!^)See/MATCH/g; print "'$_'\n"; # 'See spot run. MATCH spot jump.' # Replace 'See' unless lookabehind finds the anchor $_ = "See spot run. See spot jump."; s/(?<!^)See/MATCH/g; # 'See spot run. MATCH spot jump.' print "'$_'\n";

    -Blake

Re: (dooberwah) I'm don't think that gives the same results
by Anonymous Monk on Feb 21, 2002 at 22:33 UTC
    When having a zero-width pattern inside the assertion it doesn't matter in which direction you look. It's zero width. It's like saying that you jump 0 meters up in the air, or 0 meters down into the ground. You're still not moving. Sure, it might make more sense to say you jumped 0 meter up from the ground than down in the ground, but effectively it's still the same thing.

    I used look-ahead because if I recall correct it's faster, and it was supposted to be fast. Plus it's one byte shorter, and he wanted prettiness. I consider (?!) prettier than (?<!).

    Cheers,
    -Anomo
      Instead of just trusting the documentation I went and did my own tests on differences in regex assertions. Here are my results:

      dooberwah@kyle:~$ perl -e 'print "foobar" =~ /(?<=foo)bar/, "\n";' 1 dooberwah@kyle:~$ perl -e 'print "foobar" =~ /(?=foo)bar/, "\n";' dooberwah@kyle:~$

      As you can see, trying to use a look-ahead assertion in place of a look-behind assertion yealds no results. I certainly hope that we're still talking about the same thing. You got me a little confused with the jumping analogy :-). If your actually talking about something different please just tell me.

      -Ben Jacobs (dooberwah)
      http://dooberwah.perlmonk.org
      "one thing i can tell you is you got to be free"

        Now you've really confused yourself. :)

        Your tests are irrelevant in this case. I was using a zero-width assertion. "foo" is not zero-width.

        Just consider the second regex. That cannot be true, no matter what string you try it on. Because (?=foo) looks if the next three chars are "foo", but then you at the same time try to match "bar". So that will never be true.

        What a look-behind does is just to set how many steps behind current position it should look. In your case it's three because "foo" is three bytes long. You might be familiar with that look-behinds cannot be variable length. This is closely related to that implementation. Besides that there's no fundamental difference between look-behinds and look-aheads. A look-ahead just steps zero steps back and hence start looking at the current position. The limitation of only being able to use a constant-width patterns for look-behinds is checked at regex compile-time, and at regex run-time the regex engine uses the same method for both types of assertions. Theoretically the look-ahead takes X steps back, it's just that X is always 0.

        If the look-behind pattern then is zero-width, the engine takes zero steps back to start it's matching, and thus effectively is the same as a look-ahead.

        Cheers,
        -Anomo
      Examining the output of re 'debug' made me realize that there's not speed difference between the look-ahead and look-behind. At least not on my perl.

      -Anomo

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://146773]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (7)
As of 2024-04-16 11:31 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found