Backport pull request #17858 from jellyfin/release-12.z

Improve SeriesNameRegex

Original-merge: f98daa19e8

Merged-by: crobibero <cody@robibe.ro>

Backported-by: Cody Robibero <cody@robibe.ro>
This commit is contained in:
Shadowghost authored and Cody Robibero committed 2026-09-15 11:13:50 -04:00
1 parent 89af37462e
commit 3f2b560883
2 files changed
+13 -5

No files matched your search

+8 -5
View File
@@ -10,11 +10,14 @@ namespace Emby.Naming.TV
public static partial class SeriesResolver
{
/// <summary>
/// Regex that matches strings of at least 2 characters separated by a dot or underscore.
/// Used for removing separators between words, i.e turns "The_show" into "The show" while
/// preserving names like "S.H.O.W".
/// Regex that matches a run of dots or underscores that separates two words, where a word is
/// at least 2 characters long. Used for removing separators between words, i.e turns
/// "The_show" into "The show" while preserving acronyms like "S.H.O.W", whose single letters
/// are a word on neither side. Whitespace bounds a word too, so the dot in
/// "Marvel's Agents of S.H.I.E.L.D." is read against the "S" beside it rather than against
/// the whole run of words before it.
/// </summary>
[GeneratedRegex(@"((?<a>[^\._]{2,})[\._]*)|([\._](?<b>[^\._]{2,}))")]
[GeneratedRegex(@"(?<=[^\s\._]{2})[\._]+|[\._]+(?=[^\s\._]{2})")]
private static partial Regex SeriesNameRegex();
/// <summary>
@@ -60,7 +63,7 @@ namespace Emby.Naming.TV
if (!string.IsNullOrEmpty(seriesName))
{
seriesName = SeriesNameRegex().Replace(seriesName, "${a} ${b}").Trim();
seriesName = SeriesNameRegex().Replace(seriesName, " ").Trim();
}
return new SeriesInfo(path)
@@ -20,6 +20,11 @@ namespace Jellyfin.Naming.Tests.TV
[InlineData("/some/path/The Show s02e10 720p hdtv", "The Show")]
[InlineData("/some/path/The Show s02e10 the episode 720p hdtv", "The Show")]
[InlineData("/some/path/1923 (2022)", "1923")]
// A dotted acronym keeps its dots when it follows words, whether they are space or dot separated
[InlineData("/some/path/Marvel's Agents of S.H.I.E.L.D.", "Marvel's Agents of S.H.I.E.L.D.")]
[InlineData("Marvel's.Agents.of.S.H.I.E.L.D.", "Marvel's Agents of S.H.I.E.L.D.")]
[InlineData("The.Show.S.H.O.W", "The Show S.H.O.W")]
[InlineData("/some/path/Dawson's Creek", "Dawson's Creek")]
public void SeriesResolverResolveTest(string path, string name)
{
var res = SeriesResolver.Resolve(_namingOptions, path);