Home > Software engineering >  How to get tv show episode and session number from title
How to get tv show episode and session number from title

Time:11-12

I'm try to get tvhsow season and episode number from the title

I try following code which works but it also picking up title like xxxxe 3 as episode 3

$episode = $title | Select-String -Pattern "E(\d )", "E (\d )", "Episode (\d )" | % {$_.Matches.Groups[1].Value}
$season = $title | Select-String -Pattern "S(\d )", "S (\d )", "Season (\d )" | % {$_.Matches.Groups[1].Value} 

How to i make sure that I can pick up the season number and episode from any of these formats.

  • xxx S01E01
  • xxxe 1 S01E01
  • xxx S01 E01
  • xxx 01x01
  • xxx Season 01 Episode 01

CodePudding user response:

Assuming the following

  1. Seasons and episodes will always be 2 (or more) numbers
  2. Seasons and episodes will always be at the end of the filename.

I would recommend anchoring to the end of the name with the regex pattern. From there we account for 0 or more characters before a period (file extension), 1 literal period (for the extension), 0 or more characters between the period and the episode, and 0 or more characters between the season and the episode.

$examples = @'
xxx S01E02.avi
xxxe 1 S02E03.mp3
xxx S03 E04.mov
xxx 04x05.png
xxx Season 05 Episode 06.wav
'@ -split [environment]::NewLine

$examples | ForEach-Object {
    if($_ -match '. (\d{2,}).*(\d{2,}).*\..*$'){
        "Season: {0}  Episode: {1}" -f $matches.1,$matches.2
    }
}

This will output

Season: 01  Episode: 02
Season: 02  Episode: 03
Season: 03  Episode: 04
Season: 04  Episode: 05
Season: 05  Episode: 06

You didn't show how you populated $title, so it was assumed to just be a string. However if you wanted to apply to file objects, you have a couple of options.

We can leave the regex pattern alone and use the Name property.

$videolist = Get-Childitem -Path path\to\movies -Filter *.whatever

foreach($video in $videolist){
    if($video.Name -match '. (\d{2,}).*(\d{2,}).*\..*$'){
        "Season: {0}  Episode: {1}" -f $matches.1,$matches.2
    }
}

or

We can use the BaseName property and adjust the regex slightly.

$videolist = Get-Childitem -Path path\to\movies -Filter *.whatever

foreach($video in $videolist){
    if($video.BaseName -match '. (\d{2,}).*(\d{2,}).*$'){
        "Season: {0}  Episode: {1}" -f $matches.1,$matches.2
    }
}

CodePudding user response:

You could construct a regex string that parses out the season and episode numbers like this:

$examples = 'xxx S01E01','xxxe 1 S01E03','xxx S06 E01','xxx 01x01','xxx Season 01 Episode 02'

foreach ($title in $examples) {
    if ($title -match '(?:(?:S(?:eason)?)?\s*(\d )[\sx]*)(?:(?:E(?:pisode)?)?\s*(\d ))') {
        $season  = [int]$matches[1]
        $episode = [int]$matches[2]

        # just to display the output:
        [PsCustomObject]@{
            Title   = $title
            Season  = $season
            Episode = $episode
        }
    }
}

Output:

Title                    Season Episode
-----                    ------ -------
xxx S01E01                    1       1
xxxe 1 S01E03                 1       3
xxx S06 E01                   6       1
xxx 01x01                     1       1
xxx Season 01 Episode 02      1       2

Regex details:

(?:                # Match the regular expression below
   (?:             # Match the regular expression below
      S            # Match the character “S” literally
      (?:          # Match the regular expression below
         eason     # Match the characters “eason” literally
      )?           # Between zero and one times, as many times as possible, giving back as needed (greedy)
   )?              # Between zero and one times, as many times as possible, giving back as needed (greedy)
   \s              # Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      *            # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
   (               # Match the regular expression below and capture its match into backreference number 1
      \d           # Match a single digit 0..9
                   # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   )
   [\sx]           # Match a single character present in the list below
                   # A whitespace character (spaces, tabs, line breaks, etc.)
                   # The character “x”
      ?            # Between zero and one times, as many times as possible, giving back as needed (greedy)
)
(?:                # Match the regular expression below
   (?:             # Match the regular expression below
      E            # Match the character “E” literally
      (?:          # Match the regular expression below
         pisode    # Match the characters “pisode” literally
      )?           # Between zero and one times, as many times as possible, giving back as needed (greedy)
   )?              # Between zero and one times, as many times as possible, giving back as needed (greedy)
   \s              # Match a single character that is a “whitespace character” (spaces, tabs, line breaks, etc.)
      *            # Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
   (               # Match the regular expression below and capture its match into backreference number 2
      \d           # Match a single digit 0..9
                   # Between one and unlimited times, as many times as possible, giving back as needed (greedy)
   )
)

I have changed some of your examples to make it clearer the numbers are correctly found

  • Related