-3

I have a very lot of list in a text file something like below:

001.Porus.2017.S01E01.The.Epic.Story.Of.A.Warrior.720.x264.mp4
002.Porus.2017.S01E01.Welcome.With.A.Fight.720.x264.mp4
003.Porus.2017.S01E01.Anusuya.Stays.in.Poravs.720.x264.mp4
004.Porus.2017.S01E01.Olympia.Prays.For.A.Child.720.x264.mp4
.................

I want to replace all E01 in S01E01 with a number in a front of each list. Output I want :

001.Porus.2017.S01E001.The.Epic.Story.Of.A.Warrior.720.x264.mp4
002.Porus.2017.S01E002.Welcome.With.A.Fight.720.x264.mp4
003.Porus.2017.S01E003.Anusuya.Stays.in.Poravs.720.x264.mp4
004.Porus.2017.S01E004.Olympia.Prays.For.A.Child.720.x264.mp4

......................

Btw, I'm using the following codes;

$list = file("list.txt", FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
$string = "";

foreach($list as $index => $entry)
{
   $string .= str_pad($index + 1, 3, '0', STR_PAD_LEFT) . "." . $entry . ", ";
}

$string = substr($string, 0 , -2);
$get = explode(",", $string);
$phr = implode("<br>", array_values(array_unique($get)));
print_r($phr); 

1 Answers1

0
<pre>
<?php 

$arr = [
            '001.Porus.2017.S01E01.The.Epic.Story.Of.A.Warrior.720.x264.mp4',
            '002.Porus.2017.S01E01.Welcome.With.A.Fight.720.x264.mp4',
            '003.Porus.2017.S01E01.Anusuya.Stays.in.Poravs.720.x264.mp4',
            '004.Porus.2017.S01E01.Olympia.Prays.For.A.Child.720.x264.mp4'
        ];

$your_next_number = "some_number";

$modified_values = [];

foreach($arr as $each_value){
    $modified_values[] = str_replace("S01E01","S01".$your_next_number,$each_value);
    //$your_next_number = something;some change that you want to make to your next iterable number.
}

print_r($modified_values);

OUTPUT

Array
(
    [0] => 001.Porus.2017.S01some_number.The.Epic.Story.Of.A.Warrior.720.x264.mp4
    [1] => 002.Porus.2017.S01some_number.Welcome.With.A.Fight.720.x264.mp4
    [2] => 003.Porus.2017.S01some_number.Anusuya.Stays.in.Poravs.720.x264.mp4
    [3] => 004.Porus.2017.S01some_number.Olympia.Prays.For.A.Child.720.x264.mp4
)

UPDATE

You can replace the code inside the foreach with the code below. Credits to @ArtisticPhoenix for providing this improvisation and explanation of it.

foreach($arr as $each_value){
    $modified_values[] = preg_replace('/^(\d+)([^S]+)(S01E)(\d+)/', '\1\2\3\1', $each_value);
}
  • ^(\d+) => This is group 1. Capture (^ at the start) and digits (\d) one or more (+).

  • ([^S])+ => This is group 2. Capture anything but a capital S ([^S]) one or more (+).

  • (S01E)=> This is group 3. Capture S01E as it is.

  • (\d+) - This is group 4. Capture digits present after (S01E).

Note that group numbers have 1 based indexing since group 0 is the entire regex.

Replacement Part:

  • The replacement is \1\2\3\1.
  • The syntax \ followed by an integer(represents a group number) is known as backreferencing. This says that match the same set of characters you got from matching that group.
  • So, put the 1st,2nd and 3rd capture back where they came from, then the 4th capture is replaced with the 1st, this is the initial digits replacing the last digits in the match.

So, let's take 001.Porus.2017.S01E01.The.Epic.Story.Of.A.Warrior.720.x264.mp4 as an example-

(\d+)([^S]+)(S01E)(\d+) matches this way => (001)(.Porus.2017.)(S01E)(01)

Hence, replacement makes it as (001)(.Porus.2017.)(S01E)(001)(notice the last change because of \1 at the end in the replacement \1\2\3\1. Rest of the string remains the same anyway.

nice_dev
  • 17,053
  • 2
  • 21
  • 35
  • In your code `$your_next_number` is a static number (its always the same), I don't see how this answers the question when they want sequential numbers, also it has no correlation to the first number, personally I would do, `preg_replace('/^(\d+)([^S]+)(S01E)(\d+)/', '\1\2\3\1', $each_value);` For example: http://sandbox.onlinephpfunctions.com/code/e13e880dd2a7ebd6216e1e029eeeef83b38a7684 – ArtisticPhoenix Aug 09 '18 at 06:24
  • `$your_next_number` is technically static in my code but I have `$your_next_number = something;` also.So, I left it to the OP. He can do whatever he wants to do with it, increment or get it from the database etc. – nice_dev Aug 09 '18 at 07:57
  • 1
    Sure, but the example I put above (which I would have made an answer) not only has sequential numbers, but it pulls the number from the row itself. This insures that `$your_next_number` is the same as the first part of the row which the OP stated `I want to replace all E01 in S01E01 with a number in a front of each list`. Don't get me wrong, I'm not criticizing your answer or saying its wrong. I just wanted to show that it can be done exactly how it was asked in the question with some Regex. Also if you notice in my example I borrowed a large part of your code, Cheers! – ArtisticPhoenix Aug 09 '18 at 15:25
  • 1
    To explain my example a touch the Regex `^(\d+)` capture (^ at the start) and digits (\d) one or more (+). Then capture anything but a capital S ([^S]) one or more (+). Then capture (S01E) literal. Then capture the digits to be replaced. It's necessary to capture all this so it can be replaced. The replacement is `\1\2\3\1` put the 1st 2nd 3rd capture back where they came from, then the 4th capture is replaced with the 1st, this is the initial digits replacing the last digits int he match. – ArtisticPhoenix Aug 09 '18 at 15:30
  • @ArtisticPhoenix Yes, your solution suits better for the OP's question. I have updated my answer :) – nice_dev Aug 09 '18 at 17:04