in reply to Re^4: /g option not making s// find all matches (updated)
in thread /g option not making s// find all matches

DUP of Re^5: /g option not making s// find all matches (updated): Please REAP.

\G (?<! \A)   (?! \A) \G ... kind of hurts my brain ...

I got to wondering about all that and thought I might try to clarify it a bit, if only for my own benefit. Say we have the problem "match (and capture) the first  \w character that is not at the start of the string that is also on a  \b boundary." From the foregoing discussion,  m{ (?! \A) \b (\w) }xms does the trick:

c:\@Work\Perl\monks>perl -wMstrict -le "print qq{'$1'} if 'ab-cd' =~ m{ (?! \A) (\w) }xms; print qq{'$1'} if 'ab-cd' =~ m{ \b (\w) }xms; print qq{'$1'} if 'ab-cd' =~ m{ (?! \A) \b (\w) }xms; print qq{'$1'} if 'ab-cd' =~ m{ \b (?! \A) (\w) }xms; " 'b' 'a' 'c' 'c'
Leaving out either zero-width assertion makes the match fail. The order of the two assertions doesn't matter because it's a logical conjunction, and if there are no side-effects (and there aren't: we're just examining match position and not matching and consumng any characters, i.e., changing the match position), then A and B and B and A are equivalent.

So what about the  (?! \A) versus  (?<! \A) look-ahead/behind business. Here's how I think of it: If you're at the North Pole, in which direction do you have to go to get to the North Pole? The question is moot: You can go exactly zero meters in any direction because you're at the North Pole! Similarly, if your match position is at the start of a string, in which direction do you have to "look" to "see" the start of the string? For the  \A zero-width assertion,  \A  (?= \A)  (?<= \A) are all exactly equivalent. The same reasoning applies to negated assertions:  (?! \A)  (?<! \A) are equivalent. Indeed, I think the same reasoning applies to all zero-width assertions. Here's a Test::More demo to bolster your confidence (as it did mine):

c:\@Work\Perl\monks>perl -wMstrict -le "use Test::More 'no_plan'; use Test::NoWarnings; ;; my @regexes = ( 'negative look-ahead to \A', qr{ (?! \A) \b (\w) }xms, qr{ \b (?! \A) (\w) }xms, qr{ (?! \A) (?! \B) (\w) }xms, qr{ (?! \B) (?! \A) (\w) }xms, qr{ (?! \A) (?<! \B) (\w) }xms, qr{ (?<! \B) (?! \A) (\w) }xms, 'negative look-behind to \A', qr{ (?<! \A) \b (\w) }xms, qr{ \b (?<! \A) (\w) }xms, qr{ (?<! \A) (?! \B) (\w) }xms, qr{ (?! \B) (?<! \A) (\w) }xms, qr{ (?<! \A) (?<! \B) (\w) }xms, qr{ (?<! \B) (?<! \A) (\w) }xms, 'all together now', qr{ \b (?! \A) (?! \B) (?<! \A) (?<! \B) (\w) }xms, ); ;; REGEX: for my $rx (@regexes) { if (ref $rx ne 'Regexp') { note $rx; next REGEX; } 'ab-cd' =~ $rx; ok $1 eq 'c', qq{$rx works}; } ;; done_testing; " # negative look-ahead to \A ok 1 - (?msx-i: (?! \A) \b (\w) ) works ok 2 - (?msx-i: \b (?! \A) (\w) ) works ok 3 - (?msx-i: (?! \A) (?! \B) (\w) ) works ok 4 - (?msx-i: (?! \B) (?! \A) (\w) ) works ok 5 - (?msx-i: (?! \A) (?<! \B) (\w) ) works ok 6 - (?msx-i: (?<! \B) (?! \A) (\w) ) works # negative look-behind to \A ok 7 - (?msx-i: (?<! \A) \b (\w) ) works ok 8 - (?msx-i: \b (?<! \A) (\w) ) works ok 9 - (?msx-i: (?<! \A) (?! \B) (\w) ) works ok 10 - (?msx-i: (?! \B) (?<! \A) (\w) ) works ok 11 - (?msx-i: (?<! \A) (?<! \B) (\w) ) works ok 12 - (?msx-i: (?<! \B) (?<! \A) (\w) ) works # all together now ok 13 - (?msx-i: \b (?! \A) (?! \B) (?<! \A) (?<! \B) (\w) ) works 1..13 ok 14 - no warnings 1..14


Give a man a fish:  <%-{-{-{-<