public static Path Parse(string path) { var regex = GetRegex(); var groupNames = regex.GetGroupNames(); var parts = path.Substring(1, path.Length - 1).Split('/'); var segments = new List <Segment>(); foreach (var item in parts) { var match = regex.Match(item); var groups = match.Groups; if (match.Groups[SegmentStructure.GroupNames.StaticSegment].Success) { segments.Add(new StaticSegment() { Value = groups[SegmentStructure.GroupNames.StaticSegment].Value }); } else if (match.Groups[SegmentStructure.GroupNames.DynamicSegment].Success) { var segment = new DynamicSegment(); segment.Value = groups[SegmentStructure.GroupNames.DynamicSegment].Value; var dynamicSegmentGroup = match.Groups[SegmentStructure.GroupNames.DynamicSegment]; var elements = new List <Element>(); for (int i = 1; i < match.Groups.Count; i++) { //Console.WriteLine(groupNames[i]); var group = match.Groups[i]; foreach (Capture capture in group.Captures) { elements.Add(new Element() { GroupName = groupNames[i], Index = capture.Index, Value = capture.Value }); //Console.WriteLine(capture.Index + "\t" + capture.Value); } } var segmentParts = new List <Part>(); foreach (var element in elements.OrderBy(x => x.Index)) { switch (element.GroupName) { case SegmentStructure.GroupNames.SegmentEnd: case SegmentStructure.GroupNames.StaticPart: segmentParts.Add( new Part { Value = element.Value, IsParameter = false, ParameterName = null }); break; case SegmentStructure.GroupNames.Parameter: segmentParts.Add( new Part { Value = element.Value, IsParameter = true, ParameterName = element.Value.Substring(1, element.Value.Length - 2) }); break; default: break; } } segment.Parts = segmentParts.ToArray(); segments.Add(segment); } else { throw new Exception(string.Format("Unkown segment type \"{0}\" in path \"{1}\"", item, path)); } } return(new Path { Segments = segments.ToArray() }); }
static bool CheckDynamicSegment( DynamicSegment dynamicSegment, string pathSegment, IDictionary <string, RouteValue> parameters ) { var parts = dynamicSegment.Parts; var lastPart = parts[parts.Length - 1]; if (!lastPart.IsParameter) { if (!pathSegment.EndsWith(lastPart.Value)) { return(false); } pathSegment = pathSegment.Substring(0, pathSegment.Length - lastPart.Value.Length); } for (int j = 0; j < parts.Length; j++) { var isLastPart = j == parts.Length - 1; if (!lastPart.IsParameter && isLastPart) { continue; } var part = parts[j]; if (!part.IsParameter) { if (pathSegment.Length < part.Value.Length) { return(false); } pathSegment = pathSegment.Substring(part.Value.Length, pathSegment.Length - part.Value.Length); } else { var isLastParameterFollowedByStaticPart = part.IsParameter && j == parts.Length - 2 && !lastPart.IsParameter; if (isLastParameterFollowedByStaticPart) { var parameterValue = new RouteValue(pathSegment); parameters.Add(part.ParameterName, parameterValue); } else if (!isLastPart) { var nextPart = parts[j + 1]; if (nextPart.IsParameter) { throw new Exception("Two dynamic parts within the same segment have to be seperated by a static part!"); } var indexOfNextStaticPart = pathSegment.IndexOf(nextPart.Value); if (indexOfNextStaticPart < 0) { return(false); } var parameterValue = new RouteValue(pathSegment.Substring(0, indexOfNextStaticPart)); parameters.Add(part.ParameterName, parameterValue); pathSegment = pathSegment.Substring(indexOfNextStaticPart, pathSegment.Length - indexOfNextStaticPart); } else { var parameterValue = pathSegment; parameters.Add(lastPart.ParameterName, new RouteValue(parameterValue)); } } } return(true); }