in reply to How to capture backwards using regex?

It looks like you reinvented a poor man's pos()

Different approaches come to mind:

Update

I like Corion's solution best, in terms of pure regex solutions.

Cheers Rolf
(addicted to the Perl Programming Language :)
see Wikisyntax for the Monastery

Replies are listed 'Best First'.
Re^2: How to capture backwards using regex?
by LanX (Saint) on Nov 10, 2024 at 13:10 UTC
    For completeness

    > A "pure" regex approach is to use a positive look-behind assertion

    use v5.12; use warnings; use Test::More; say "Version: $]"; sub test { my ($msg, $str, $exp) = @_; my $pos = index($str, "*"); die "NO POINTER <$msg> in <$str>" if $pos == -1; substr($str,$pos,1) = ""; die "MULTIPLE POINTERS <$msg> in <$str>" if index($str,"*") >-1; no warnings 'experimental'; # no better category available + ??? my $match = join "", ($str =~ m/^.{$pos}(*plb:(\d{0,254}))(\d+)/) +; is ($match,$exp,$msg); } test "In the middle", 'World 12*3456 Hello 789 ' => "123456" ; test "At the start" , 'World *123456 Hello 789 ' => "123456" ; test "At the end" , 'World 12345*6 Hello 789 ' => "123456" ; test "Before" , 'Wo*rld 123456 Hello 789 ' => "" ; test "Right before" , 'World* 123456 Hello 789 ' => "" ; test "After" , 'World 123456 *Hello 789 ' => "" ; test "Right after" , 'World 123456* Hello 789 ' => "" ; test "In next Nr" , 'World 123456 Hello 7*89 ' => "789" ; test "Nr at start" , '*123456 Hello' => "123456" ; test "Nr at end" , 'World 12345*6' => "123456" ; test "Pos at end" , 'World 123456*' => "" ; done_testing;

    Version: 5.038002 ok 1 - In the middle ok 2 - At the start ok 3 - At the end ok 4 - Before ok 5 - Right before ok 6 - After ok 7 - Right after ok 8 - In next Nr ok 9 - Nr at start ok 10 - Nr at end ok 11 - Pos at end 1..11

    Remarks

    Unfortunately with variable length this still seems experimental with 5.38 ...

    • Variable length positive lookbehind with capturing is experimental in regex;
    and I had to use a hard limit of 254 instead of *
    • Lookbehind longer than 255 not implemented
    Strangely enough I couldn't find a dedicated warnings category and had to disable all "experimental" warnings locally.

    Updates

    had to fix tests because of C&P errors leading to multiple pointers, fixed test() to catch those errors.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

Re^2: How to capture backwards using regex?
by harangzsolt33 (Deacon) on Nov 10, 2024 at 17:05 UTC
    Yeah, I've played around with positive look-behind regex, and it just didn't want to work. Of course, I'm using TinyPerl 5.8, so I'm a decade or two behind. lol But surprisingly, Corion's solution works flawlessly on TinyPerl 5.8, so that's great!
      Look behind used to only work with fixed length patterns. IIRC.

      That's most likely also related to the "experimental" status of my code.

      > But surprisingly, Corion's solution works flawlessly

      Doesn't surprise me that's a very old feature, could be even Perl4.

      The idea of Pos and related stuff is very sed/awk-ish, and text processing was one of the main objectives of Perl4.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      see Wikisyntax for the Monastery