Allow a trailing fansub revision tag in SxxExx parsing

"S01E01v2" (a fixed re-release of an episode) glued the version marker
directly onto the episode number with no separator, so the word-boundary
check after the digits never matched and the whole file fell through as
unparsed. Verified live: some shows had zero episode files linked because
every release happened to be a v2.
This commit is contained in:
Breadway 2026-07-21 19:32:13 +08:00
parent 54818f5f05
commit 60d01657eb
2 changed files with 19 additions and 1 deletions

View file

@ -131,6 +131,16 @@ mod tests {
assert_eq!(p.title_normalized, "Ascendance of a Bookworm"); assert_eq!(p.title_normalized, "Ascendance of a Bookworm");
} }
#[test]
fn parses_sxxexx_with_a_trailing_fansub_revision_tag() {
// "v2" glued directly onto the episode number ("a fixed re-release
// of this episode") previously broke the word-boundary check
// entirely, leaving season/episode both None.
let p = parse("[Judas] Chainsaw Man - S01E01v2 1080p WEB-DL");
assert_eq!(p.season, Some(1));
assert_eq!(p.episode, Some(1));
}
#[test] #[test]
fn parses_subsplease_dash_episode_with_group_and_hash() { fn parses_subsplease_dash_episode_with_group_and_hash() {
let p = parse("[SubsPlease] Honzuki no Gekokujou S4 - 13 (1080p) [A4FE0990].mkv"); let p = parse("[SubsPlease] Honzuki no Gekokujou S4 - 13 (1080p) [A4FE0990].mkv");

View file

@ -38,8 +38,16 @@ static YEAR_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r"[(\[](19|20)\d{2
static BARE_YEAR_RE: LazyLock<Regex> = static BARE_YEAR_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"\b((?:19|20)\d{2})\b").unwrap()); LazyLock::new(|| Regex::new(r"\b((?:19|20)\d{2})\b").unwrap());
// The trailing `v\d+` is a fansub revision tag ("v2" = "second release of
// this episode, fixed encode/subs") stuck directly onto the episode number
// with no separator — "S01E01v2". Without consuming it before the `\b`,
// the boundary check fails outright (digit→letter isn't a word boundary),
// so the whole pattern silently doesn't match and the file falls through
// to unparsed (verified live: every v2 release of several shows, e.g. an
// entire show that only had v2 releases, ended up with zero linked
// episode files during a library scan).
static SXXEXX_RE: LazyLock<Regex> = static SXXEXX_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"(?i)\bS(\d{1,2})E(\d{1,3})\b").unwrap()); LazyLock::new(|| Regex::new(r"(?i)\bS(\d{1,2})E(\d{1,3})(?:v\d+)?\b").unwrap());
static SXX_DASH_EP_RE: LazyLock<Regex> = static SXX_DASH_EP_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"(?i)\bS(\d{1,2})\s*-\s*(\d{1,3})\b").unwrap()); LazyLock::new(|| Regex::new(r"(?i)\bS(\d{1,2})\s*-\s*(\d{1,3})\b").unwrap());
static SEASON_PACK_RE: LazyLock<Regex> = static SEASON_PACK_RE: LazyLock<Regex> =