diff --git a/IsIdentifiable/Reporting/Reports/FailureStoreReport.cs b/IsIdentifiable/Reporting/Reports/FailureStoreReport.cs index ed2ff617..8db94c8b 100644 --- a/IsIdentifiable/Reporting/Reports/FailureStoreReport.cs +++ b/IsIdentifiable/Reporting/Reports/FailureStoreReport.cs @@ -173,8 +173,15 @@ public static IEnumerable Deserialize(IFileInfo oldFile, Action lo if (!string.IsNullOrWhiteSpace(partRule.IfColumn) && !string.Equals(partRule.IfColumn, problemField, StringComparison.InvariantCultureIgnoreCase)) continue; - foreach (var part in parts.Where(x => partRule.Covers(x, problemValue))) - toRemove.Add(part); + foreach (var part in parts) + { + var origOffset = part.Offset; + if (partRule.Covers(part, problemValue)) + { + part.Offset = origOffset; + toRemove.Add(part); + } + } } parts = parts.Except(toRemove); /* TEMP */ diff --git a/IsIdentifiable/Rules/RegexRule_PartTemp.cs b/IsIdentifiable/Rules/RegexRule_PartTemp.cs index 14684301..70228b4c 100644 --- a/IsIdentifiable/Rules/RegexRule_PartTemp.cs +++ b/IsIdentifiable/Rules/RegexRule_PartTemp.cs @@ -57,18 +57,38 @@ private void RebuildPartRegex() IfPartPatternRegex = new Regex(_ifPartPatternString, (CaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase) | RegexOptions.Compiled); } + private static void FixupOffset(FailurePart failurePart, string problemValue) + { + if (problemValue.Substring(failurePart.Offset, failurePart.Word.Length) == failurePart.Word) + return; + + // Try looking ahead first, then back + var origOffset = failurePart.Offset; + try + { + while (problemValue.Substring(failurePart.Offset, failurePart.Word.Length) != failurePart.Word) + failurePart.Offset++; + } + catch (ArgumentOutOfRangeException) + { + failurePart.Offset = origOffset; + while (problemValue.Substring(failurePart.Offset, failurePart.Word.Length) != failurePart.Word) + failurePart.Offset--; + } + } + public bool Covers(FailurePart failurePart, string problemValue) { if (As != failurePart.Classification) return false; + // Fixes any offsets that have been mangled by file endings etc. + FixupOffset(failurePart, problemValue); + bool matchesBefore = false; if (!string.IsNullOrWhiteSpace(WordBefore)) { var problemValueUpToOffset = problemValue[..(failurePart.Offset + failurePart.Word.Length)]; - if (!problemValueUpToOffset.EndsWith(failurePart.Word)) - throw new Exception("Invlaid data: actual word and word at offset did not match"); - var wordBeforeRegex = new Regex($"\\b{WordBefore}\\s+{IfPartPattern.TrimStart('^')}", (CaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase)); matchesBefore = wordBeforeRegex.Matches(problemValueUpToOffset).Any(); } @@ -77,9 +97,6 @@ public bool Covers(FailurePart failurePart, string problemValue) if (!string.IsNullOrWhiteSpace(WordAfter)) { var problemValueFromOffset = problemValue[failurePart.Offset..]; - if (!problemValueFromOffset.StartsWith(failurePart.Word)) - throw new Exception("Invlaid data: actual word and word at offset did not match"); - var wordAfterRegex = new Regex($"{IfPartPattern.TrimEnd('$')}\\s+{WordAfter}\\b", (CaseSensitive ? RegexOptions.None : RegexOptions.IgnoreCase)); matchesAfter = wordAfterRegex.Matches(problemValueFromOffset).Any(); } @@ -92,6 +109,10 @@ public bool Covers(FailurePart failurePart, string problemValue) { return true; } + else if (!string.IsNullOrWhiteSpace(WordBefore) || !string.IsNullOrWhiteSpace(WordAfter)) + { + return false; + } return IfPartPatternRegex.Matches(failurePart.Word).Any(); }