Q:

Regular expression to extract a numeric value on a changing position within a variable string

How can I extract the bold numeric part of a string, when the most of the string can change? /data/ is always present and followed by the relevant, variable, numeric part (in this case 123456).
differentcontentLocationhttps://example.com/api/result/13548/data/123456differentstuffincludingwhitespacesandnewlines8484
$str = "differentcontentLocationhttps://example.com/api/result/13548/data/123456differentstuffincludingwhitespacesandnewlines8484";

$str2 = "differentcontentLocationhttps://example.com/api/result/13548/data/123456";

In this example I need 123456. The only constant parts in the string are /data/ and maybe the first part of the URL, like https://.
preg_match("@/data/([0-9]+)([^0-9]+)@siU", $str, $matches);

Results in Array ( [0] => /data/123456d [1] => 123456 [2] => d ), what would be acceptable. But if there's nothing following the relevant numeric part, like in $str2, this expression fails. I've tried to make the tailing part optional with preg_match("@/ads/([0-9]+)(([^0-9]+)?)@siU", $x, $matches);, but it fails, too; returning only the first number of the numeric part.

A:

The U greediness swapping modifier makes all greedy subpattern lazy here, you should remove it together with ([^0-9]+). You also do not need DOTALL modifier because there is no . in your pattern whose behavior could be modified with that s flag.
preg_match("@/data/([0-9]+)@i", $str, $matches);

Now, the pattern will match:

/data/ - a sequence of literal chars
([0-9]+) - Group 1 capturing 1+ digits (same as (\d+))

See the PHP demo.
$str = "differentcontentLocationhttps://e...content-available-to-author-only...e.com/api/result/13548/data/123456differentstuffincludingwhitespacesandnewlines8484";
$str2 = "differentcontentLocationhttps://e...content-available-to-author-only...e.com/api/result/13548/data/123456";
preg_match("@/data/([0-9]+)@i", $str, $matches);
print_r($matches); // Array ( [0] => /data/123456  [1] => 123456  )
preg_match("@/data/([0-9]+)@i", $str2, $matches2);
print_r($matches2); // Array ( [0] => /data/123456  [1] => 123456  )

