private void ComputeRawRegex(RegexAlias alias, List <RegexAlias> computedAliases) { // Add this as a computed dependency to detect circular dependencies computedAliases.Add(alias); foreach (var subAliasName in GetSubAliasNames(alias)) { var matchName = string.Concat("%{", subAliasName, "}"); // Find an alias with the specified name and put its // regex pattern into the current alias' pattern var subAlias = _aliases.FirstOrDefault(x => x.Name.Equals(subAliasName, StringComparison.InvariantCultureIgnoreCase)); if (subAlias != null) { // If the subAlias has already been computed this run, // we have a circular dependency if (computedAliases.Contains(subAlias)) { throw new InvalidOperationException("Circular dependency detected while computing alias dependencies"); } // Compute the sub alias' regex ComputeRawRegex(subAlias, computedAliases.ToList()); alias.RegexPattern = alias.RegexPattern.Replace(matchName, subAlias.RegexPattern); } } }
private IEnumerable <string> GetSubAliasNames(RegexAlias alias) { return(Regex.Matches(alias.RegexPattern, AliasPattern) .Cast <Match>() .Select(x => x.Value.Substring(2, x.Value.Length - 3)) .Distinct()); }
public void Can_Resolve_Deep_Dependent_Aliases() { const string inputPattern = "%{test2}"; const string expectedResult = "abcdefg"; var alias = new RegexAlias { Name = "test1", RegexPattern = @"%{test3}" }; var alias2 = new RegexAlias { Name = "test2", RegexPattern = @"%{test1}%{test4}" }; var alias3 = new RegexAlias { Name = "test3", RegexPattern = "abcd" }; var alias4 = new RegexAlias { Name = "test4", RegexPattern = "efg" }; var resolver = new RegexAliasResolver(new[] { alias, alias2, alias3, alias4 }); var pattern = resolver.ResolveToRegex(inputPattern); Assert.AreEqual(expectedResult, pattern, "Returned pattern was not correct"); }
public void Can_Resolve_Basic_Alias() { const string inputPattern = "testing%{numbers}"; const string expectedResult = "testing[0-9]+"; var alias = new RegexAlias { Name = "numbers", RegexPattern = @"[0-9]+" }; var resolver = new RegexAliasResolver(new[] {alias}); var pattern = resolver.ResolveToRegex(inputPattern); Assert.AreEqual(expectedResult, pattern, "Returned pattern was not correct"); }
public void Aliases_Are_Case_Insensitive() { const string inputPattern = "%{NUMBERS}"; const string expectedResult = "[0-9]+"; var alias = new RegexAlias { Name = "numbers", RegexPattern = @"[0-9]+" }; var resolver = new RegexAliasResolver(new[] { alias }); var pattern = resolver.ResolveToRegex(inputPattern); Assert.AreEqual(expectedResult, pattern, "Returned pattern was not correct"); }
public void Aliases_Can_Refer_To_Other_Aliases_With_Case_Insensitivity() { const string inputPattern = "%{test1}"; const string expectedResult = "[0-9]+"; var alias = new RegexAlias { Name = "test1", RegexPattern = @"%{TEST2}" }; var alias2 = new RegexAlias { Name = "test2", RegexPattern = @"[0-9]+" }; var resolver = new RegexAliasResolver(new[] { alias2, alias }); var pattern = resolver.ResolveToRegex(inputPattern); Assert.AreEqual(expectedResult, pattern, "Returned pattern was not correct"); }
public void Null_Aliases_Are_Ignored() { const string inputPattern = "%{letters}%{numbers}"; const string expectedResult = "%{letters}[0-9]+"; var alias = new RegexAlias { Name = "numbers", RegexPattern = @"[0-9]+" }; var resolver = new RegexAliasResolver(new[] { alias, null }); var pattern = resolver.ResolveToRegex(inputPattern); Assert.AreEqual(expectedResult, pattern, "Returned pattern was not correct"); }
public void IP_Address_Test() { var alias = new RegexAlias { Name = "IPAddress", RegexPattern = @"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" }; var resolver = new RegexAliasResolver(new[] { alias }); const string pattern = "connection from %{IPAddress}"; const string test1 = "connection from 192.168.0.1"; const string test2 = "connection from 555.555.555.555"; // Resolve the pattern into becomes "connection from \b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b" var regexPattern = resolver.ResolveToRegex(pattern); // Run the regex var match1 = Regex.Match(test1, regexPattern); var match2 = Regex.Match(test2, regexPattern); Assert.IsTrue(match1.Success); Assert.IsFalse(match2.Success); }
public void Exception_Thrown_When_Multiple_Aliases_Have_The_Same_Name() { var alias = new RegexAlias { Name = "test1", RegexPattern = @"%{test2}%{test2}" }; var alias2 = new RegexAlias { Name = "test1", RegexPattern = @"abc" }; new RegexAliasResolver(new[] { alias, alias2 }); }
public void Exception_Thrown_When_Circular_Alias_Dependency_Exists() { var alias = new RegexAlias { Name = "test1", RegexPattern = @"%{test2}" }; var alias2 = new RegexAlias { Name = "test2", RegexPattern = @"%{test3}" }; var alias3 = new RegexAlias { Name = "test3", RegexPattern = @"%{test1}" }; new RegexAliasResolver(new[] {alias, alias2, alias3}); }
public void Chained_IP_Address_Test_WihTags1() { var alias = new RegexAlias { Name = "IPDigit", RegexPattern = @"(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" }; var alias2 = new RegexAlias { Name = "IPAddress", RegexPattern = @"%{IPDigit}\.%{IPDigit}\.%{IPDigit}\.%{IPDigit}" }; var resolver = new RegexAliasResolver(new[] { alias, alias2 }); const string pattern = "%{IPAddress:ip1} %{IPAddress:ip2}"; const string test1 = "192.168.0.1 192.168.0.2"; const string test2 = "555.555.555.555 555.555.555.555"; var regexPattern = resolver.ResolveToRegex(pattern); // Run the regex var match1 = Regex.Match(test1, regexPattern); var match2 = Regex.Match(test2, regexPattern); Assert.IsTrue(match1.Success); Assert.IsFalse(match2.Success); if (match1.Success) { var regex = new Regex(regexPattern); var namedCaptures = regex.MatchNamedCaptures(test1); Assert.AreEqual(namedCaptures["ip1"], "192.168.0.1"); Assert.AreEqual(namedCaptures["ip2"], "192.168.0.2"); } }
public void Can_Resolve_Multiple_Aliases() { const string inputPattern = "%{letters}%{numbers}"; const string expectedResult = "[a-z]+[0-9]+"; var alias = new RegexAlias { Name = "numbers", RegexPattern = @"[0-9]+" }; var alias2 = new RegexAlias { Name = "letters", RegexPattern = @"[a-z]+" }; var resolver = new RegexAliasResolver(new[] { alias, alias2 }); var pattern = resolver.ResolveToRegex(inputPattern); Assert.AreEqual(expectedResult, pattern, "Returned pattern was not correct"); }
public void Can_Resolve_Dependent_Aliases_With_Multiple_References_To_The_Same_Alias() { const string inputPattern = "%{test1}"; const string expectedResult = "abcabc"; var alias = new RegexAlias { Name = "test1", RegexPattern = @"%{test2}%{test2}" }; var alias2 = new RegexAlias { Name = "test2", RegexPattern = @"abc" }; var resolver = new RegexAliasResolver(new[] { alias, alias2 }); var pattern = resolver.ResolveToRegex(inputPattern); Assert.AreEqual(expectedResult, pattern, "Returned pattern was not correct"); }