/// <summary> /// Parse a (relative) path against a pattern and extract the various tokens. /// </summary> /// <param name="path">The actual path. For example: /Pet(Dog)/Toy(Bone)</param> /// <param name="pattern">The pattern. ie: /Pet({Kind})/Toy({Name}</param> /// <returns>A list of individual tokens. For example: Pet; Kind; Toy; Name</returns> public static IEnumerable<RouteToken> Parse(string path, string pattern) { List<RouteToken> result = new List<RouteToken>(); if (null == path || null == pattern) return result; if (path == pattern) { RouteToken token = new RouteToken() { Kind = RouteTokenKind.Resource, Value = SanitizeResource(path) }; token.Name = token.Value; result.Add(token); return result; } var regex = ConvertPatternToRegularExpression(pattern); System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(regex); var pathMatches = r.Matches(path); if (pathMatches.Count != 1) return result; System.Text.RegularExpressions.Regex r2 = new Regex(regex); var patternMatches = r2.Matches(pattern); if (patternMatches.Count != 1) return result; // There should be a single match. // The Groups will be of the form: Full // ResourceName // ResourceIdentifier // Tail if (pathMatches[0].Groups.Count == 1) return result; var full = pathMatches[0].Groups[0].Value; int offset = 1; // The matches will be in groups of three because of the regular expression: // resourceName // resourceIdentifier // tail while (offset < pathMatches[0].Groups.Count) { // var resourceName = m.Groups["resourceName"]; // var resourceIdentifier = m.Groups["resourceIdentifier"]; // var tail = m.Groups["tail"]; string resourceName = ""; string resourceIdentifier = ""; if (offset != pathMatches[0].Groups.Count) { resourceName = pathMatches[0].Groups[offset].Value; RouteToken token = new RouteToken() { Kind = RouteTokenKind.Resource, Value = SanitizeResource(resourceName) }; token.Name = token.Value; result.Add(token); offset++; } if (offset != pathMatches[0].Groups.Count) { resourceIdentifier = pathMatches[0].Groups[offset].Value; RouteToken token = new RouteToken() { Kind = RouteTokenKind.Property, Value = resourceIdentifier }; token.Name = patternMatches[0].Groups[offset].Value.Replace("{", "").Replace("}", ""); result.Add(token); offset++; } if (offset != pathMatches[0].Groups.Count) { // Tail. offset++; } } return result; }
/// <summary> /// Parse the pattern and extract the tokens. /// </summary> /// <param name="pattern">The path / pattern (typically from a condition). ie: /Pet/{Kind}</param> /// <returns>The parsed route. ie: Pet, Kind</returns> public static IEnumerable<RouteToken> Parse(string pattern) { List<RouteToken> result = new List<RouteToken>(); if (null == pattern) return result; if (pattern == "") { RouteToken token = new RouteToken() { Kind = RouteTokenKind.Resource, Value = "" }; result.Add(token); return result; } System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(RegularExpression); var matches = r.Matches(pattern); if (matches.Count == 0) return result; foreach (System.Text.RegularExpressions.Match match in matches) { int offset = 1; while (offset < match.Groups.Count) { // var resourceName = m.Groups["resourceName"]; // var resourceIdentifier = m.Groups["resourceIdentifier"]; // var tail = m.Groups["tail"]; string resourceName = ""; string resourceIdentifier = ""; if (offset != match.Groups.Count) { resourceName = match.Groups[offset].Value; RouteToken token = new RouteToken() { Kind = RouteTokenKind.Resource, Value = SanitizeResource(resourceName) }; result.Add(token); // Edge case: A fixed /Resource is passed in. In this case, if the resource is the same as the pattern, we are done. if (resourceName == match.Value) { break; } offset++; } if (offset != match.Groups.Count) { resourceIdentifier = match.Groups[offset].Value; RouteToken token = new RouteToken() { Kind = RouteTokenKind.Property, Value = resourceIdentifier.Replace("{", "").Replace("}", "") }; result.Add(token); offset++; } if (offset != match.Groups.Count) { // Tail. offset++; } } } return result; }