Search code examples
regexpcre

Regex (PCRE): Match all digits conditional upon presence of a string


Using PCRE, I want to capture only and all digits in a single line, but only if a certain string (say "STRING99") is present anywhere within that line.

For example, consider these two cases:

a1 STRING99 2b c3d

a1 2b c3d

In the first case, I want the result to be "19923". In the second case, I want an empty result.

I am not sure this is possible. It might work with a variable-length lookbehind, but this is not supported in PCRE. Furthermore, something like (?=.*STRING99.*$)(\D|(\d))* WOULD work, but "a repeated capturing group will only capture the last iteration", meaning the second capturing group only captures the last digit. I am unable to find a workaround for this.

(This is obviously not hard to achieve with 2 consecutive Regex operations, but I want it in one formula.)


Solution

  • You may use this PCRE regex in preg_replace:

    ^(?!.*STRING99).*(*SKIP)|\D+
    

    RegEx Demo

    RegEx Details:

    • ^: Start
    • (?!.*STRING99): Lokahead to check if we have STRING99 anywhere in input
    • .*(*SKIP): Match rest of the input till end and skip it
    • |: OR
    • \D+: Match 1+ non-digit

    PHP Code:

    $repl = preg_replace('~^(?!.*STRING99).*(*SKIP)|\D+~', '', $str);