// Copyright © WireMock.Net using System; using System.Linq; using System.Text.RegularExpressions; using AnyOfTypes; using JetBrains.Annotations; using Stef.Validation; using WireMock.Constants; using WireMock.Extensions; using WireMock.Models; using WireMock.RegularExpressions; using WireMock.Util; namespace WireMock.Matchers; /// /// Regular Expression Matcher /// /// /// public class RegexMatcher : IStringMatcher, IIgnoreCaseMatcher { private readonly AnyOf[] _patterns; private readonly Regex[] _expressions; private readonly bool _useRegexExtended; /// public MatchBehaviour MatchBehaviour { get; } /// /// Initializes a new instance of the class. /// /// The pattern. /// Ignore the case from the pattern. /// Use RegexExtended (default = true). /// The to use. (default = "Or") public RegexMatcher( [RegexPattern] AnyOf pattern, bool ignoreCase = false, bool useRegexExtended = true, MatchOperator matchOperator = MatchOperator.Or) : this(MatchBehaviour.AcceptOnMatch, [pattern], ignoreCase, useRegexExtended, matchOperator) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The pattern. /// Ignore the case from the pattern. /// Use RegexExtended (default = true). /// The to use. (default = "Or") public RegexMatcher( MatchBehaviour matchBehaviour, [RegexPattern] AnyOf pattern, bool ignoreCase = false, bool useRegexExtended = true, MatchOperator matchOperator = MatchOperator.Or) : this(matchBehaviour, [pattern], ignoreCase, useRegexExtended, matchOperator) { } /// /// Initializes a new instance of the class. /// /// The match behaviour. /// The patterns. /// Ignore the case from the pattern. /// Use RegexExtended (default = true). /// The to use. (default = "Or") public RegexMatcher( MatchBehaviour matchBehaviour, [RegexPattern] AnyOf[] patterns, bool ignoreCase = false, bool useRegexExtended = true, MatchOperator matchOperator = MatchOperator.Or) { _patterns = Guard.NotNull(patterns); IgnoreCase = ignoreCase; _useRegexExtended = useRegexExtended; MatchBehaviour = matchBehaviour; MatchOperator = matchOperator; var options = RegexOptions.Compiled | RegexOptions.Multiline; if (ignoreCase) { options |= RegexOptions.IgnoreCase; } _expressions = patterns.Select(p => useRegexExtended ? new RegexExtended(p.GetPattern(), options) : new Regex(p.GetPattern(), options, RegexConstants.DefaultTimeout)).ToArray(); } /// public virtual MatchResult IsMatch(string? input) { var score = MatchScores.Mismatch; Exception? exception = null; if (input != null) { try { score = MatchScores.ToScore(_expressions.Select(e => e.IsMatch(input)).ToArray(), MatchOperator); } catch (Exception ex) { exception = ex; } } return MatchResult.From(Name, MatchBehaviourHelper.Convert(MatchBehaviour, score), exception); } /// public virtual AnyOf[] GetPatterns() { return _patterns; } /// public virtual string Name => nameof(RegexMatcher); /// public bool IgnoreCase { get; } /// public MatchOperator MatchOperator { get; } /// public virtual string GetCSharpCodeArguments() { return $"new {Name}" + $"(" + $"{MatchBehaviour.GetFullyQualifiedEnumValue()}, " + $"{MappingConverterUtils.ToCSharpCodeArguments(_patterns)}, " + $"{CSharpFormatter.ToCSharpBooleanLiteral(IgnoreCase)}, " + $"{CSharpFormatter.ToCSharpBooleanLiteral(_useRegexExtended)}, " + $"{MatchOperator.GetFullyQualifiedEnumValue()}" + $")"; } }