in reply to How to capture backwards using regex?

You can set pos of the string to continue matching, and then capture the digits to the left and right of the continuation point (\G):

#!/usr/bin/perl use 5.020; use experimental 'signatures'; use Test::More; sub digits( $S, $pos ) { pos($S) = $pos; return ($S =~ m/\b(\d*\G\d*)\b/c) ? $1 : undef; } is digits( 'Hello World 123456 !!! 789 ...', 14 ), '123456', "In middl +e"; is digits( '12345 World 123456 !!! 789 ...', 14 ), '123456', "No digit +s before"; is digits( '12345 World 123456 !!! 789 ...', 17 ), '123456', "At end"; is digits( '12345 World 123456 !!! 789 ...', 12 ), '123456', "At start +"; done_testing;

Replies are listed 'Best First'.
Re^2: How to capture backwards using regex?
by harangzsolt33 (Deacon) on Nov 10, 2024 at 16:28 UTC
    Wow, THANK YOU!!!

    This looks like the simplest and most straight-forward solution. Thank you!

    Now, I did notice that the \b word boundary modifier forces it work only if the number is preceded by a whitespace, and I don't want that behavior. And the "c" at the end causes a warning to appear. It says, "Use of /c modifier is meaningless without /g at C:\DESKTOP\test.pl line 11." The second \d* should be \d+ because for some reason if I use \d* it fails to capture the very last digit.

    I wrote a modified version of this to see what's happening, and I think, this is precisely how I want it to work:


    #!/usr/bin/perl use strict; use warnings; my $S = " 45 ee33ee#555+'3210>{579}/8888\"~-099.2:"; for (my $i = 0; $i < length($S); $i++) { pos($S) = $i; print("\n :", (($S =~ m/(\d*\G\d+)/) ? $1 : ''), ": \tptr=$i \ts +ubstr=", substr($S, $i)); }

    This program outputs the following:

    :: ptr=0 substr= 45 ee33ee#555+'3210>{579}/8888"~-099.2 +: :45: ptr=1 substr=45 ee33ee#555+'3210>{579}/8888"~-099.2: :45: ptr=2 substr=5 ee33ee#555+'3210>{579}/8888"~-099.2: :: ptr=3 substr= ee33ee#555+'3210>{579}/8888"~-099.2: :: ptr=4 substr=ee33ee#555+'3210>{579}/8888"~-099.2: :: ptr=5 substr=e33ee#555+'3210>{579}/8888"~-099.2: :33: ptr=6 substr=33ee#555+'3210>{579}/8888"~-099.2: :33: ptr=7 substr=3ee#555+'3210>{579}/8888"~-099.2: :: ptr=8 substr=ee#555+'3210>{579}/8888"~-099.2: :: ptr=9 substr=e#555+'3210>{579}/8888"~-099.2: :: ptr=10 substr=#555+'3210>{579}/8888"~-099.2: :555: ptr=11 substr=555+'3210>{579}/8888"~-099.2: :555: ptr=12 substr=55+'3210>{579}/8888"~-099.2: :555: ptr=13 substr=5+'3210>{579}/8888"~-099.2: :: ptr=14 substr=+'3210>{579}/8888"~-099.2: :: ptr=15 substr='3210>{579}/8888"~-099.2: :3210: ptr=16 substr=3210>{579}/8888"~-099.2: :3210: ptr=17 substr=210>{579}/8888"~-099.2: :3210: ptr=18 substr=10>{579}/8888"~-099.2: :3210: ptr=19 substr=0>{579}/8888"~-099.2: :: ptr=20 substr=>{579}/8888"~-099.2: :: ptr=21 substr={579}/8888"~-099.2: :579: ptr=22 substr=579}/8888"~-099.2: :579: ptr=23 substr=79}/8888"~-099.2: :579: ptr=24 substr=9}/8888"~-099.2: :: ptr=25 substr=}/8888"~-099.2: :: ptr=26 substr=/8888"~-099.2: :8888: ptr=27 substr=8888"~-099.2: :8888: ptr=28 substr=888"~-099.2: :8888: ptr=29 substr=88"~-099.2: :8888: ptr=30 substr=8"~-099.2: :: ptr=31 substr="~-099.2: :: ptr=32 substr=~-099.2: :: ptr=33 substr=-099.2: :099: ptr=34 substr=099.2: :099: ptr=35 substr=99.2: :099: ptr=36 substr=9.2: :: ptr=37 substr=.2: :2: ptr=38 substr=2: :: ptr=39 substr=: