Question

I've been working on this for hours, and I can't find a way to replace the page number in a url without destroying it.

I have this kind of Urls:

http: //example.com/s/192090/1/text

Where "192090" is the post id, 1 is the page number, and "text" is the post title.

What I want is to replace the page number, keeping the rest of the url:

http: //example.com/s/192090/2/text

http: //example.com/s/192090/3/text

http: //example.com/s/192090/12/text

http: //example.com/s/192090/542/text

And so on.

The problem is, I can't get the regex right.

If i try:

preg_replace("/[0-9]+/[0-9]+/",'$0/2',$url);

I get:

http://example.com/s/192090/1/2/text

I've tried a lot of regex combinations, but I have no experience whatsover with Regex.

The problem is that the /s/NUM_POST/NUM_PAGE both are variable in length. I need to keep the first, and replace the second without messing with the NUM_POST, or the blog title at the end.

Any ideas?

Was it helpful?

Solution

This works and doesn't have to deal with back references, which make my head hurt:

$url = '/s/192090/1/2/text';
$page_number = 55;
$pattern = '/\/(s)\/(\d+)\/(\d+)\/(.*)/';
$replacement = '/$1/$2/'.$page_number.'/$4';

echo preg_replace($pattern, $replacement, $url);

However, it assumes you have that leading /s/ which could be changed to just:

'/\/(.*)\/(\d+)\/(\d+)\/(.*)/'

OTHER TIPS

Use grouping (with (..)) and a back-reference to that group:

$newUrl = preg_replace('#s/([0-9]+)/[0-9]+#', 's/\1/' . $newPageNr, $url);

\1 means the first group.

Why dont you try and use explode() ?

$example  = "http: //example.com/s/192090/1/text";
$info = explode("/", $example);
$pid = $info[4];
$page = $info[5];
$text = $info[6];

Here's another approach, via exploding and imploding:

$url = "http://example.com/s/192090/1/text";
$parsed = parse_url($url); //generate associative array
$exploded = explode("/", $parsed['path']); //explodes path

//replaces the crucial number
$exploded[3] = 7;

$parsed['path'] = implode("/", $exploded);//recreates the path
//concatenates the URL - may also be able to use http_build_url here
$newURL = $parsed['scheme']  ."://" . $parsed['host'] . $parsed['path']; 
echo $newURL;

Here is what I did to make the replacement:

$new_digit = 1978;

$url = 'http://example.com/s/192090/1/text';

print "Original URL: ".$url;

$url = preg_replace('~s/\d+/\K\d+(?=/)~', $new_digit, $url);

print "\n     New URL: ".$url;

This outputs:

Original URL: http://example.com/s/192090/1/text
     New URL: http://example.com/s/192090/1978/text

Here is the explanation of the REGEX:

s/   \d+/   \K    \d+    (?=/)
^      ^     ^     ^       ^
1      2     3     4       5
  1. s/ This is an anchor point and not really necessary. You can start the expression with the second item and still get the same thing. I put it in there because I wanted to show some sort of anchor.
  2. \d+/ Here, we are looking for one or more digits followed by a forward slash.
  3. \K This tells the Regular Expression to start over from here. Now that we've made a successful match up to this point, we want to pull out everything after this. (We made a match, but we don't want to capture it, we just to note its location so we know where to start replacing from.
  4. \d+ One or more digits. This is the only part of the expression that will actually be captured. Consequently, this is the only part of the expression that will be replaced.
  5. (?=/) This is a lookahead to find the slash after the digits it captured. Lookaheads are not captured and all this really does is set the ending for the \d+. Since the slash is not a digit, it will not be matched by the \d+ and it is not really necessary here either. I'm solely using it to show an anchor. The expression would work just fine without it.

Without the unnecessary anchors (items 1 & 5), you could prune the expression down to this if you wanted:

~\d+/\K\d+~

And still get the same results.

Here is a working demo

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top