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
- Seasons and episodes will always be 2 (or more) numbers
- 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