比较两个没有参数值的 URI/URL 终结点

Compare two URI/URL endpoints without parameter values

提问人:Arsen Khachaturyan 提问时间:10/18/2023 最后编辑:JonasArsen Khachaturyan 更新时间:10/26/2023 访问量:41

问:

假设我有以下两个 URI:

  1. var uri1 = "/rest/api/projects/{projectName}/statuses"
  2. var uri2 = "/rest/api/projects/XXX/statuses"

如图所示,它们仅在参数定义和实际值上有所不同。 但是,在比较它们时,我想跳过参数名称/值检查。

因此,比较这两个 URI 应返回 true:

string.Equals(uri1, uri2) == true
C# 字符串 URL URI

评论

0赞 Brian Tompsett - 汤莱恩 10/20/2023
注意标记 [api] 说明:“请勿使用此标记”

答:

1赞 Arsen Khachaturyan 10/18/2023 #1

经过一些非生产性的研究,我想出了以下逻辑。

溶液

public static class UrlExtensions
{
    public static bool CompareUrlsExceptParameters(this string urlToCompareFrom, string urlToCompareWith)
    {
        string pattern = @"\{[^/]*?\}"; // find out the {parameter} location in the main URL

        var match = Regex.Match(urlToCompareFrom, pattern);

        if (match.Success && match.Index < urlToCompareWith.Length) // found parameters in {}
        {
            var parameterName = match.Success ? match.Value : string.Empty;

            var index = match.Index;
            var replaceEndInd = urlToCompareWith.IndexOf('/', index);

            if (replaceEndInd == -1) // this might be the case when {parameter} found at the end of URL
            {
                replaceEndInd = urlToCompareWith.Length;
            }

            var parameterValue = urlToCompareWith.Substring(index, replaceEndInd - index);

            var resultUrl = urlToCompareFrom.Replace(parameterName, parameterValue);

            if (Regex.Match(resultUrl, pattern).Success) // contains more parameter(s)
            {
                return CompareUrlsExceptParameters(resultUrl, urlToCompareWith);
            }

            var isEqual = string.Equals(resultUrl, urlToCompareWith, StringComparison.OrdinalIgnoreCase); // compare the strings ignoring case

            return isEqual;
        }

        return urlToCompareFrom.Contains(urlToCompareWith); // nothing found use ordinary comparison
    }
}

使用/测试

Assert.True("https://rest/api/projects/{projectName}".CompareUrlsExceptParameters("https://rest/api/projects/XXX"));
Assert.True("rest/api/projects/{projectName}/statuses".CompareUrlsExceptParameters("rest/api/projects/XXX/statuses"));
Assert.True("rest/api/projects/{projectName}/statuses/{statusId}".CompareUrlsExceptParameters("rest/api/projects/XXX/statuses/1"));
Assert.True("https://rest/api/projects/XXX".CompareUrlsExceptParameters("https://rest/api/projects/XXX"));

Assert.False("rest/api/projects/{projectName}/statuses/{statusId}/other".CompareUrlsExceptParameters("rest/api/projects/XXX/statuses/1"));
Assert.False("rest/api/projects/{projectName}/statuses/{statusId}".CompareUrlsExceptParameters("rest/api/projects/XXX/statuses/1/other"));
Assert.False("rest/api/projects/{projectName}/resources".CompareUrlsExceptParameters("rest/api/projects/XXX/statuses/1/other"));
Assert.False("rest/api/projects/{projectName}/resources".CompareUrlsExceptParameters("rest/api/statuses"));
Assert.False("rest/api/project/resources".CompareUrlsExceptParameters("rest/api/project/statuses"));