How to do this regex?

7

I have some difficulties using REGEX, so I would like help separating the following text example:

1ª Temporada - Nome da temporada
01 - Nome do ep um
02 - Nome do ep dois
03 - Nome do ep três
...
2ª Temporada - Nome da temporada
01 - Nome do ep um
02 - Nome do ep dois
03 - Nome do ep três
...

I need to make a explode and create an array called episodios and within these other arrays, each array corresponding to a season, in practice would be:

$episodios = array();
$episodios[1] = array(
    1 => Nome do ep um
    2 => Nome do ep dois
    3 => Nome do ep três
);
$episodios[2] = array(
    1 => Nome do ep um
    2 => Nome do ep dois
    3 => Nome do ep três
);

The first key in $ episodes indicates the season, and the season keys indicate the episode number. How can I make this separation?

Below is an example of the original text that I want to separate:

1ª Temporada – Shinigami Daikou
001. O Dia em que me Tornei Shinigami
002. Um Trabalho de Shinigami
003. O Desejo do Irmão mais Velho, o Desejo da Irmã mais Nova
004. Periquito Amaldiçoado
2ª Temporada – Invasão a Soul Society
026. Formação! A Pior Companhia
027. Libere o Golpe Final!
028. Orihime está sendo Visada
3ª Temporada – Fuga da Soul Society
052. Renji, Juramento da Alma! Luta Mortal com Byakuya
053. A Tentação de Ichimaru Gin, Resolução da Destruição
054. Um Juramento Realizado! Pegue Rukia Devolta
    
asked by anonymous 09.04.2018 / 21:19

3 answers

9

Even with regex it will be necessary to loop, regex alone will not succeed, for example:

<?php

$filmes = array();

$str = '1ª Temporada – Shinigami Daikou
001. O Dia em que me Tornei Shinigami
002. Um Trabalho de Shinigami
003. O Desejo do Irmão mais Velho, o Desejo da Irmã mais Nova
004. Periquito Amaldiçoado
2ª Temporada – Invasão a Soul Society
026. Formação! A Pior Companhia
027. Libere o Golpe Final!
028. Orihime está sendo Visada
3ª Temporada – Fuga da Soul Society
052. Renji, Juramento da Alma! Luta Mortal com Byakuya
053. A Tentação de Ichimaru Gin, Resolução da Destruição
054. Um Juramento Realizado! Pegue Rukia Devolta';

$linhas = preg_split('#[\r\n]+#', $str);

$ultima_temporada = 0;

foreach ($linhas as $value) {

    //Extrai o numero da temporada
    if (preg_match('#(\d+)ª[^a-z]+?temporada#i', $value, $temporada)) {

        $ultima_temporada = intval($temporada[1]);
        $filmes[$ultima_temporada] = array();

    //Extrai o nome e numero do episodio
    } elseif (preg_match('#(\d+)[^a-z]+([a-z].*?)$#i', $value, $episodio)) {

        $filmes[$ultima_temporada][ intval($episodio[1]) ] = $episodio[2];

    }
}

//Exibe
print_r($filmes);

The variable $ultima_temporada contains the last season found, and in the next loop if it finds an episode it will be in the array that will receive the episodes, if the next row is a season then it will update the variable so that next season only receive the values, and so on.

While the intval($episodio[1]) converts the episode number value to integer (not to have forward zero)

Example on IDEONE . Output:

Array
(
    [1] => Array
        (
            [1] => Nome do ep um
            [2] => Nome do ep dois
            [3] => Nome do ep três
        )

    [2] => Array
        (
            [1] => Nome do ep um
            [2] => Nome do ep dois
            [3] => Nome do ep três
        )

)

Regex

Explaining the regex that extracts the seasons:

(\d+)ª[^a-z]+?temporada

 ^    ^
 .    .
 .    .
 .    .
 .    .
 .    . 
 .    .... verifica se existe algum separador entre temporada
 .
 .... Pega o numero da temporada

Explaining the regex that extracts the episodes:

(\d+)[^a-z]+([a-z].*?)$

 ^    ^       ^       ^
 .    .       .       .
 .    .       .       ... Para ir até o final da string
 .    .       .
 .    .       ..... Para pegar qualquer coisa, no caso o nome do episódio
 .    . 
 .    .... Identifica se existe um separador, ou seja o espaço é opcional
 .
 .... Pega o numero do episódio
    
09.04.2018 / 22:52
7

I did it without REGEX because I find it easier.

$text =    "1ª Temporada - Nome da temporada
            01 - Nome do ep um
            02 - Nome do ep dois
            03 - Nome do ep três
            2ª Temporada - Nome da temporada
            01 - Nome do ep um
            02 - Nome do ep dois
            03 - Nome do ep três
            ";

$texto = explode("\n", $text);
$episodios = array();
$y = -1;
for( $x = 0; $x < count($texto); $x++){
    if(stristr($texto[$x], 'Temporada')){
        $y++;
        $episodios[$y] = array();
    } else {
        $episodios[$y][] = trim($texto[$x]);
    }
}
print_r($episodios);

Another option would be to do this:

$text = fopen("text.txt", "r"); // seu arquivo que contém o texto
$episodios = array();
$y = -1;
while(!feof($text)){
    $linha = fgets($text, 1024);
    if(stristr($linha, 'Temporada')){
        $y++;
        $episodios[$y] = array();
    } else {
        $episodios[$y][] = trim($linha);
    }
}

print_r($episodios);
    
09.04.2018 / 22:08
2

You can also use this regex:

$pattern = "/[\d].*/";

It will get each line that starts with a number creating an array at the% index of the catch:

Thenyoucanmountthearraywith[0]andpreg_match_all(similartoforeachoftheotheranswer):

$texto='1ªTemporada-Nomedatemporada01-Nomedoepum02-Nomedoepdois03-Nomedoeptrês2ªTemporada-Nomedatemporada01-Nomedoepum02-Nomedoepdois03-Nomedoeptrês';$pattern="/[\d].*/";
$resultado = preg_match_all($pattern, $texto, $matches);

$episodios = array();

$x = 1;
foreach($matches[0] as $items){
   if(stristr($items, 'Temporada')){
      $episodios[$x] = array();
      $x++;
   }else{
      $episodios[$x-1][] = $items;
   }
}

print_r($episodios);

See on Ideone

    
09.04.2018 / 23:23