parent
97d4063cf3
commit
a27b6eb63e
@ -0,0 +1,72 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.Exceptions;
|
||||
|
||||
namespace NzbDrone.Core.Restrictions
|
||||
{
|
||||
public static class PerlRegexFactory
|
||||
{
|
||||
private static Regex _perlRegexFormat = new Regex(@"/(?<pattern>.*)/(?<modifiers>[a-z]*)", RegexOptions.Compiled);
|
||||
|
||||
public static bool TryCreateRegex(string pattern, out Regex regex)
|
||||
{
|
||||
var match = _perlRegexFormat.Match(pattern);
|
||||
|
||||
if (!match.Success)
|
||||
{
|
||||
regex = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
regex = CreateRegex(match.Groups["pattern"].Value, match.Groups["modifiers"].Value);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Regex CreateRegex(string pattern, string modifiers)
|
||||
{
|
||||
var options = GetOptions(modifiers);
|
||||
|
||||
// For now we simply expect the pattern to be .net compliant. We should probably check and reject perl-specific constructs.
|
||||
return new Regex(pattern, options | RegexOptions.Compiled);
|
||||
}
|
||||
|
||||
private static RegexOptions GetOptions(string modifiers)
|
||||
{
|
||||
var options = RegexOptions.None;
|
||||
|
||||
foreach (var modifier in modifiers)
|
||||
{
|
||||
switch (modifier)
|
||||
{
|
||||
case 'm':
|
||||
options |= RegexOptions.Multiline;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
options |= RegexOptions.Singleline;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
options |= RegexOptions.IgnoreCase;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
options |= RegexOptions.IgnorePatternWhitespace;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
options |= RegexOptions.ExplicitCapture;
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentException("Unknown or unsupported perl regex modifier: " + modifier);
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using NzbDrone.Common.Cache;
|
||||
|
||||
namespace NzbDrone.Core.Restrictions
|
||||
{
|
||||
public interface ITermMatcher
|
||||
{
|
||||
bool IsMatch(string term, string value);
|
||||
}
|
||||
|
||||
public class TermMatcher : ITermMatcher
|
||||
{
|
||||
private ICached<Predicate<string>> _matcherCache;
|
||||
|
||||
public TermMatcher(ICacheManager cacheManager)
|
||||
{
|
||||
_matcherCache = cacheManager.GetCache<Predicate<string>>(GetType());
|
||||
}
|
||||
|
||||
public bool IsMatch(string term, string value)
|
||||
{
|
||||
return GetMatcher(term)(value);
|
||||
}
|
||||
|
||||
public Predicate<string> GetMatcher(string term)
|
||||
{
|
||||
return _matcherCache.Get(term, () => CreateMatcherInternal(term), TimeSpan.FromHours(24));
|
||||
}
|
||||
|
||||
private Predicate<string> CreateMatcherInternal(string term)
|
||||
{
|
||||
Regex regex;
|
||||
if (PerlRegexFactory.TryCreateRegex(term, out regex))
|
||||
{
|
||||
return regex.IsMatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new CaseInsensitiveTermMatcher(term).IsMatch;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class CaseInsensitiveTermMatcher
|
||||
{
|
||||
private readonly string _term;
|
||||
|
||||
public CaseInsensitiveTermMatcher(string term)
|
||||
{
|
||||
_term = term.ToLowerInvariant();
|
||||
}
|
||||
|
||||
public bool IsMatch(string value)
|
||||
{
|
||||
return value.ToLowerInvariant().Contains(_term);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in new issue