in reply to zero-length match increments pos()

Basically, a zero-length match isn't allowed to occur at the same position twice, whether in successive scalar matches or a single list context match. In addition to pos() being saved for each scalar, there's a flag that says whether it was zero-length or not. This is documented in http://search.cpan.org/perldoc/perlre#Repeated_patterns_matching_zero-length_substring.

The flag can be cleared if needed by setting pos: pos($foo) = pos($foo).

Replies are listed 'Best First'.
Re^2: zero-length match increments pos()
by tilly (Archbishop) on Feb 21, 2005 at 19:01 UTC
    I used to use the pos($foo) = pos($foo) trick until Klaus Weidner pointed out to me in a patch to Text::xSV the useful fact that using the obscurely documented /c modifier keeps the flag from being set in the first place. In addition to being cleaner this fixed a segfault on long strings due to an internal Perl bug.
      If //c does that, I would call it a bug. Can you show a short test case? In at least this simple case, the flag (called MINMATCH, i.e. a minimum length of 1 will be required on the next match) is set:
      $ perl -we'use Devel::Peek; ($x="abc")=~/.??/gc; Dump $x' SV = PVMG(0x10183f00) at 0x10167ca4 REFCNT = 1 FLAGS = (SMG,POK,pPOK) IV = 0 NV = 0 PV = 0x10142828 "abc"\0 CUR = 3 LEN = 4 MAGIC = 0x10147380 MG_VIRTUAL = &PL_vtbl_mglob MG_TYPE = PERL_MAGIC_regex_global(g) MG_FLAGS = 0x01 MINMATCH
      (Note that older perls have a bug where Devel::Peek doesn't correctly show the flag by name, but you can still see the bit in MG_FLAGS.)
        Gah, you're right. I misremembered what the /c patch did. It is documented in Regexp Quotelike Operators, and it keeps pos from being reset on a failed match. So I was having to assign to pos before, but for a different reason than I was just remembering. :-(