Getting variables between slash forwards in a URL

Viewed 37

Let's say I have a URL: https://somesite.com/0/posts/20/290/755653-Title.html How would I get these variables: /0/, /20/, /290/ ? Note they are variables, they will always be different.

I thought I could get them like so:

$url = '//somesite.com/0/posts/20/290/755653-Title.html'; var_dump(parse_url($url));

but the array doesn't show them as separate variables. Should it be done with a preg_replace instead? I don't think I know how. Thank you for your help.

3 Answers

One option is to use a positive lookahead with preg_match_all where you capture the pattern in a capturing group:

(?=(/\d+/))

That will match

  • (?= Positive lookahead, assert what is directly on the right is
    • (/\d+/) Match /, 1+ digits and /
  • ) Close positive lookahead

Regex demo | Php demo

For example

$re = '~(?=(/\d+/))~m';
$str = 'https://somesite.com/0/posts/20/290/755653-Title.html';

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

Result

Array
(
    [0] => /0/
    [1] => /20/
    [2] => /290/
)

If you want to get the digits only without the surrounding slashes you could add the group around the digits only

(?=/(\d+)/) 

Php demo

You could use explode() and turn the string into an array divided by the "/" delimiter.

<?php
// Example 1
$url  = "https://somesite.com/0/posts/20/290/755653-Title.html";
$pieces = explode("/", $url);
echo $pieces[0] . "<br />";
echo $pieces[1] . "<br />";
echo $pieces[2] . "<br />";
echo $pieces[3] . "<br />";
echo $pieces[4] . "<br />";
echo $pieces[5] . "<br />";
echo $pieces[5] . "<br />";
echo $pieces[6] . "<br />";
echo $pieces[7] . "<br />";

echo "<hr />";
// Example 2
$data = "https://somesite.com/0/posts/20/290/755653-Title.html";
list($first, $second, $third, $fourth, $fifth, $sixth, $seventh, $eighth) = explode("/", $url);
echo $first . "<br />";
echo $second . "<br />";
echo $third . "<br />";
echo $fourth . "<br />";
echo $fifth . "<br />";
echo $sixth . "<br />";
echo $seventh . "<br />";
echo $eighth . "<br />";

?>

Output:

https:

somesite.com
0
posts
20
20
290
755653-Title.html

https:

somesite.com
0
posts
20
290
755653-Title.html

We can try splitting on path separator, and then using array_filter with an inline function to retain only purely numerical components:

$str = 'https://somesite.com/0/posts/20/290/755653-Title.html';
$parts = explode("/", $str);
$parts = array_filter($parts, function($item) { return is_numeric($item); });
print_r($parts);

This prints:

Array
(
    [3] => 0
    [5] => 20
    [6] => 290
)

Note that this approach completely avoids the use of a formal regex, which might have performance implications if you needed to do this often in your script.

Related