diff --git a/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs
index cebd69bff..56522f3d3 100644
--- a/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs
+++ b/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs
@@ -120,7 +120,7 @@ namespace NzbDrone.Core.Test.ParserTests
ExceptionVerification.IgnoreWarns();
}
- [TestCase("[DmonHiro] The Severing Crime Edge - Cut 02 - Portrait Of Heresy [BD, 720p] [BE36E9E0]")]
+ [TestCase("THIS SHOULD NEVER PARSE")]
public void unparsable_title_should_log_warn_and_return_null(string title)
{
Parser.Parser.ParseTitle(title).Should().BeNull();
diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs
index 17b1491d3..cc9556702 100644
--- a/src/NzbDrone.Core/Parser/Parser.cs
+++ b/src/NzbDrone.Core/Parser/Parser.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
@@ -16,30 +17,26 @@ namespace NzbDrone.Core.Parser
private static readonly Regex[] ReportTitleRegex = new[]
{
+ //Episodes with airdate
+ new Regex(@"^(?
.+?)?\W*(?\d{4})\W+(?[0-1][0-9])\W+(?[0-3][0-9])(\W+|_|$)(?!\\)",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled),
+
//Anime - Absolute Episode Number + Title + Season+Episode
- new Regex(@"^(?:(?\d{2,3})(?:_|-|\s|\.)+)+(?.+?)(?:_|-|\s|\.)+(?:S?(?(?\d{2}(?!\d+)))+)",
+ new Regex(@"^(?:(?\d{2,3})(?:_|-|\s|\.)+)+(?.+?)(?:\W|_)+(?:S?(?(?\d{2}(?!\d+)))+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime - [SubGroup] Title Absolute Episode Number + Season+Episode
- new Regex(@"^(?:\[(?.+?)\](?:_|-|\s|\.))?(?.+?)(?:(?:_|-|\s|\.)+(?\d{2,3}))+(?:_|-|\s|\.)+(?:S?(?(?\d{2}(?!\d+)))+)",
+ new Regex(@"^(?:\[(?.+?)\](?:_|-|\s|\.))?(?.+?)(?:(?:\W|_)+(?\d{2,3}))+(?:_|-|\s|\.)+(?:S?(?(?\d{2}(?!\d+)))+)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime - [SubGroup] Title Season+Episode + Absolute Episode Number
- new Regex(@"^(?:\[(?.+?)\](?:_|-|\s|\.))?(?.+?)(?:_|-|\s|\.)+(?:S?(?(?\d{2}(?!\d+)))+)(?:_|\s|\.)(?:(?\d{2,3})(?:_|-|\s|\.|$)+)+",
+ new Regex(@"^(?:\[(?.+?)\](?:_|-|\s|\.))?(?.+?)(?:\W|_)+(?:S?(?(?\d{2}(?!\d+)))+)(?:\s|\.)(?:(?\d{2,3})(?:_|-|\s|\.|$)+)+",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
//Anime - [SubGroup] Title Absolute Episode Number
- new Regex(@"^\[(?.+?)\](?:_|-|\s|\.)?(?.+?)(?:(?:_|-|\s|\.)+(?\d{2,}))+",
- RegexOptions.IgnoreCase | RegexOptions.Compiled),
-
- //Anime - Title Absolute Episode Number [SubGroup]
- new Regex(@"^(?.+?)(?:(?:_|-|\s|\.)+(?\d{2,3}))+(?:.+?)\[(?.+?)\](?:\.|$)",
+ new Regex(@"^\[(?.+?)\](?:_|-|\s|\.)?(?.+?)(?:(?:\W|_)+(?\d{2,}))+",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
- //Episodes with airdate
- new Regex(@"^(?.+?)?\W*(?\d{4})\W+(?[0-1][0-9])\W+(?[0-3][0-9])(\W+|_|$)(?!\\)",
- RegexOptions.IgnoreCase | RegexOptions.Compiled),
-
//Multi-Part episodes without a title (S01E05.S01E06)
new Regex(@"^(?:\W*S?(?(?\d{1,3}(?!\d+)))+){2,}(\W+|_|$)(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
@@ -64,6 +61,10 @@ namespace NzbDrone.Core.Parser
new Regex(@"^(?.*?)(?:\W?S?(?(?\d{1}))+)+(\W+|_|$)(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
+ //Anime - Title Absolute Episode Number [SubGroup]
+ new Regex(@"^(?.+?)(?:(?:_|-|\s|\.)+(?\d{2,3}))+(?:.+?)\[(?.+?)\](?:\.|$)",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled),
+
//Supports 103/113 naming
new Regex(@"^(?.+?)?(?:\W?(?(?\d{2}(?!p|i|\d+)))+(\W+|_|$)(?!\\)",
RegexOptions.IgnoreCase | RegexOptions.Compiled),
@@ -82,7 +83,11 @@ namespace NzbDrone.Core.Parser
//Supports Season only releases
new Regex(@"^(?.+?)\W(?:S|Season)\W?(?\d{1,2}(?!\d+))(\W+|_|$)(?EXTRAS|SUBPACK)?(?!\\)",
- RegexOptions.IgnoreCase | RegexOptions.Compiled)
+ RegexOptions.IgnoreCase | RegexOptions.Compiled),
+
+ //Anime - Title Absolute Episode Number
+ new Regex(@"^(?.+?)(?:(?:_|-|\s|\.)+e(?\d{2,3}))+",
+ RegexOptions.IgnoreCase | RegexOptions.Compiled),
};
private static readonly Regex NormalizeRegex = new Regex(@"((^|\W|_)(a|an|the|and|or|of)($|\W|_))|\W|_|(?:(?<=[^0-9]+)|\b)(?!(?:19\d{2}|20\d{2}))\d+(?=[^0-9ip]+|\b)",
@@ -134,6 +139,7 @@ namespace NzbDrone.Core.Parser
if (match.Count != 0)
{
+ Debug.WriteLine(regex);
try
{
var result = ParseMatchCollection(match);
@@ -268,7 +274,8 @@ namespace NzbDrone.Core.Parser
var count = last - first + 1;
result.EpisodeNumbers = Enumerable.Range(first, count).ToArray();
}
- else if (absoluteEpisodeCaptures.Any())
+
+ if (absoluteEpisodeCaptures.Any())
{
var first = Convert.ToInt32(absoluteEpisodeCaptures.First().Value);
var last = Convert.ToInt32(absoluteEpisodeCaptures.Last().Value);