How to preg_match all the digits and not the url coded commar

Viewed 64

I the following URL https://test.example.com/blah/12345%2C80%2C8263473%2C9475834343 After the https://test.example.com/blah/part of the URL, there are numbers being separated by %2C. I want to get an array of all the numbers in the URL. The number may a positive 1 all the way up to positive infinity. There may be an infinite amount of numbers in the URL or nothing at all (in this case the array is empty).

In this scenario, I want an array like: [12345, 80, 8263473, 9475834343]

$url = "https://test.example.com/blah/12345%2C80%2C8263473%2C9475834343";

preg_match('/\b\d+\b/', $url, $matches);
print_r($matches);

However, the only element in my array is 12345

4 Answers

You could also make use of the \G anchor to get those numbers:

(?:https?://\S+?/blah/|\G(?!^))(?:%2C)?\K\d+

Explanation

  • (?: Non capture group
    • https?://\S+?/blah/ Match the protocol and till the first occurrence of /blah/
    • | Or
    • \G(?!^) Assert the current position at the end of the previous match, not at the start
  • ) Close non capture group
  • (?:%2C)? Optionally match %2C
  • \K\d+ Forget what is matched so far, and match 1+ digits

Regex demo | PHP demo

Example

$re = '`(?:https?://\S+?/blah/|\G(?!^))(?:%2C)?\K\d+`m';
$str = 'https://test.example.com/blah/12345%2C80%2C8263473%2C9475834343';

preg_match_all($re, $str, $matches);
print_r($matches[0]);

Output

Array
(
    [0] => 12345
    [1] => 80
    [2] => 8263473
    [3] => 9475834343
)

Consider just splitting on encoded characters, to generate an array of the numbers you want

$url = "https://test.example.com/blah/12345%2C80%2C8263473%2C9475834343";
$url = preg_replace("/^.*\//", "", $url);
$matches = preg_split("/%\w{2}/", $url);
print_r($matches);

This prints:

Array
(
    [0] => 12345
    [1] => 80
    [2] => 8263473
    [3] => 9475834343
)

Not sure how this would work with PhP in a working environment but would either of the following be an option to you?

%2C|(?!.*\/)(\d+)

Where you'd first match the "%2C" part and use an alternation to match groups of digits after your last forward slash to grab those groups of digits in an array. Again, I'd not be sure how you'd get an array from that 1st capture group.

If something like that would fail, maybe exclude the "%2C" part from your final array with backtracking control verbs (*SKIP)(*F) like so:

%2C(*SKIP)(*F)|(?!.*\/)\d+

A possible alternative way of writing this could be:

(?:^.*\/|%2C)(*SKIP)(*F)|\d+

Another one solution:

$url = "https://test.example.com/blah/12345%2C80%2C8263473%2C9475834343";

$decodedUrl = urldecode($url); // convert url to .../blah/12345,80
$queryListString = substr($decodedUrl, strrpos($decodedUrl, "/") + 1); // get string after last slash
$intList = explode(',', $queryListString); // convert string to array by comma

This code is very simple, so you could use it. First of all you need to make urldecode, which convert to regular string. after that make another manipulations.

Related