1
\$\begingroup\$

I have small class which interprets TV show filenames to extract the show title and episode number. Due to the nature of the filenames, I have chosen for a cleaning approach: I clean the filename first as much as possible and then extract the necessary data (instead of matching the data right away with regexp).

I'm kind of stuck on the following problem:

I have a cleanFilename() method and a getEpisodeNumber() method, which rely on each other to work but I want to be able to use them independently.

I would also like to note that the getEpisodeNumber() method requires a cleaned filename to work properly and that the cleanFilename() method requires the episode number to be removed for it to return the correct value.

NOTE: if anyone knows a better solution to extract the relevant data, please do let me know.

public function cleanFilename($filename)
{
    // run first string replace filter
    $step = str_replace($this->bad_filter, '', $filename);

    // replace underscore "_" with space " "
    $step = str_replace('_', '', $step);

    // run version filter
    $step = str_replace($this->version_filter, '', $step);

    // remove all not ascii characters
    $step = preg_replace('/[[:^print:]]/', '', $step);

    // remove everything between braces
    $step = preg_replace("/(\\[.*?\\])/is", '', $step);

    // remove everything between brackets
    $step = preg_replace("/(\\(.*\\))/is", '', $step);

    //remove episode number
    $step = str_ireplace($this->getEpisodeNumber($step, true), '', $step);

    //trim trailing dash
    $step = trim($step, ' -');

    return $step;

}

public function getEpisodeNumber($string, $filtered = false)
{
    if ($filtered === false) {
        $string = $this->cleanFilename($string);
    }

    // match integers
    $c = preg_match_all("/(\\d+)/is", $string, $matches);

    return sprintf('%02d', end($matches[0]));

}

These are some filenames:

[HorribleSubs] Shounen Hollywood - Holly Stage for 50 - 09 [480p].mkv.torrent
[DameDesuYo] Junketsu no Maria - 07 (1280x720 10bit AAC) [873A1506].mkv.torrent
[Cthuko] Shirobako - 20 [720p H264 AAC][6363865C].mkv.torrent
[Hatsuyuki]_Ansatsu_Kyoushitsu_OVA_[848x480][10bit][6BE57B34].mkv
\$\endgroup\$
1
\$\begingroup\$

This seems quite fine. I can only nitpick.

Here, either the comment is wrong or you have a bug, as the command will remove underscore instead of replacing with space:

// replace underscore "_" with space " "
$step = str_replace('_', '', $step);

Many of the expressions have unnecessary elements:

  • The /i flag in expressions that don't include case sensitive pattern
  • The grouping within (...) in expressions that don't use the capture group
  • \\ instead of a simple \

For example these can be simplified:

$step = preg_replace("/(\\[.*?\\])/is", '', $step);
$step = preg_replace("/(\\(.*\\))/is", '', $step);
$c = preg_match_all("/(\\d+)/is", $string, $matches);

To this:

$step = preg_replace("/\[.*?\]/s", '', $step);
$step = preg_replace("/\(.*\)/s", '', $step);
$c = preg_match_all("/\d+/s", $string, $matches);

I would add one more operation to remove spaces in front of dots:

$step = preg_replace('/ +\./', '.', $step);
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you for this! I generated the regex from a website, I have never gotten around to learn it. I will apply your suggestions. Also thanks for catching that bug. \$\endgroup\$ – Ortix92 Mar 7 '15 at 20:03
  • \$\begingroup\$ Typo in str_replace('_', '', $step); \$\endgroup\$ – hjpotter92 Mar 9 '15 at 10:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.