假设我有这两个网址:
var str1 = "/rest/api/projects/{projectName}/statuses"
var str2 = "/rest/api/projects/XXX/statuses"
如图所示,它们仅在参数定义和实际值上有所不同。 但是,我想在比较它们时跳过参数名称/值检查。
因此,比较这两个 URL,应该返回 true:
string.Equals(str1, str2) == true
经过一些非生产性的研究,我自己弄清楚了逻辑。
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) // 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("rest/api/project/{projectName}".CompareUrlsExceptParameters("rest/api/project/XXX"));
Assert.True("rest/api/project/{projectName}/statuses".CompareUrlsExceptParameters("rest/api/project/XXX/statuses"));
Assert.True("rest/api/project/{projectName}/statuses/{statusId}".CompareUrlsExceptParameters("rest/api/project/XXX/statuses/1"));
Assert.False("rest/api/project/{projectName}/statuses/{statusId}/other".CompareUrlsExceptParameters("rest/api/project/XXX/statuses/1"));
Assert.False("rest/api/project/{projectName}/statuses/{statusId}".CompareUrlsExceptParameters("rest/api/project/XXX/statuses/1/other"));
Assert.False("rest/api/project/{projectName}/resources".CompareUrlsExceptParameters("rest/api/project/XXX/statuses/1/other"));
Assert.False("rest/api/project/resources".CompareUrlsExceptParameters("rest/api/project/statuses"));