in reply to Match only last occurrence

Use a negative zero-width lookahead assertion:

perl -E '$x="test: 111\ntest: 222 test: 333"; $x=~/test:\s+(\d{3})(?!t +est:\s+\d{3})$/s; say $1'; 333

What the

/test:\s+(\d{3})(?!test:\s+\d{3})$/s

regex does is looks for test:, and captures the following three digits, so long as there's not another test: NNN anywhere else after it (meaning the last one in the string). The /s modifier allows you to search across newlines. I've used \s+ instead of a literal space just to ensure that it'll match any type of whitespace (tab, multiple consecutive spaces etc).

Replies are listed 'Best First'.
Re^2: Match only last occurrence (?!.*)
by tye (Sage) on May 31, 2016 at 14:52 UTC

    (Quoting part of the original code from before a silent update was done. Note that the correction that follows still applies to the 2nd version of the code but, of course, may not apply to some future version of the code if more updates are made.)

    /(\d{3})(?!\d{3})$/s

    Well, you picked an example where that works but not for the reasons that you think. Your example only works because you picked an example string that matches the much simpler:

    /(\d{3})$/s

    A regex that is actually functionally identical to your regex.

    What you wanted was more like:

    /(\d{3})(?!.*\d{3})/s

    (Update: Removed the '$' from before the last closing paren.)

    But I'd still prefer the ( ... )[-1] approach as complex regexes often lead to mistakes, as we have seen twicethrice already in this thread.

    - tye