Replace apostrophes with spaces instead of removing them in search titles

Stripping apostrophes entirely merges adjacent tokens (e.g. "t'aimais"
becomes "taimais"), causing indexer searches to return zero results for
titles containing apostrophes. Replacing with a space lets the existing
NonWord pass convert them to "+" separators, keeping tokens distinct.

Fixes #11370
This commit is contained in:
robinw0410 2026-02-28 01:31:53 +01:00
parent 89110c2cc8
commit a5706194cb
2 changed files with 10 additions and 7 deletions

View file

@ -9,16 +9,17 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
{
public class SearchDefinitionFixture : CoreTest<MovieSearchCriteria>
{
[TestCase("Betty White's Off Their Rockers", "Betty+Whites+Off+Their+Rockers")]
[TestCase("Betty Whites Off Their Rockers", "Betty+White+s+Off+Their+Rockers")]
[TestCase("Star Wars: The Clone Wars", "Star+Wars+The+Clone+Wars")]
[TestCase("Hawaii Five-0", "Hawaii+Five+0")]
[TestCase("Franklin & Bash", "Franklin+and+Bash")]
[TestCase("Chicago P.D.", "Chicago+PD")]
[TestCase("Kourtney And Khlo\u00E9 Take The Hamptons", "Kourtney+And+Khloe+Take+The+Hamptons")]
[TestCase("Betty White`s Off Their Rockers", "Betty+Whites+Off+Their+Rockers")]
[TestCase("Betty White\u00b4s Off Their Rockers", "Betty+Whites+Off+Their+Rockers")]
[TestCase("Betty Whites Off Their Rockers", "Betty+Whites+Off+Their+Rockers")]
[TestCase("Betty Whites Off Their Rockers", "Betty+Whites+Off+Their+Rockers")]
[TestCase("Betty White`s Off Their Rockers", "Betty+White+s+Off+Their+Rockers")]
[TestCase("Betty White\u00b4s Off Their Rockers", "Betty+White+s+Off+Their+Rockers")]
[TestCase("Betty Whites Off Their Rockers", "Betty+White+s+Off+Their+Rockers")]
[TestCase("Betty Whites Off Their Rockers", "Betty+White+s+Off+Their+Rockers")]
[TestCase("Moi qui taimais", "Moi+qui+t+aimais")]
public void should_replace_some_special_characters(string input, string expected)
{
Subject.SceneTitles = new List<string> { input };

View file

@ -9,7 +9,8 @@ namespace NzbDrone.Core.IndexerSearch.Definitions
{
public abstract class SearchCriteriaBase
{
private static readonly Regex SpecialCharacter = new Regex(@"['.\u0060\u00B4\u2018\u2019]", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex ApostropheCharacter = new Regex(@"['\u0060\u00B4\u2018\u2019]", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex PeriodCharacter = new Regex(@"[.]", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex NonWord = new Regex(@"[\W]", RegexOptions.IgnoreCase | RegexOptions.Compiled);
private static readonly Regex BeginningThe = new Regex(@"^the\s", RegexOptions.IgnoreCase | RegexOptions.Compiled);
@ -28,7 +29,8 @@ public static string GetCleanSceneTitle(string title)
var cleanTitle = BeginningThe.Replace(title, string.Empty);
cleanTitle = cleanTitle.Replace("&", "and");
cleanTitle = SpecialCharacter.Replace(cleanTitle, "");
cleanTitle = ApostropheCharacter.Replace(cleanTitle, " ");
cleanTitle = PeriodCharacter.Replace(cleanTitle, "");
cleanTitle = NonWord.Replace(cleanTitle, "+");
// remove any repeating +s