【发布时间】:2011-10-27 21:19:51
【问题描述】:
我一直在使用我找到的一些代码 here 来帮助我将 HTML 页面源代码中的相对 URL 转换为绝对 URL。
我想使用 RegEx,而不是 HTML 敏捷包来解决这个特定问题。
我稍微修改了代码,除了替换带有前面“/”的相对 URL 之外,它运行良好,但据我所知,似乎不包含前面斜杠的相对 URL 是不是。
我很确定问题出在初始正则表达式字符串中,因为没有尝试替换。这超出了我的正则表达式知识范围。
谁能帮我找出导致这与我描述的 URL 类型不匹配的原因?
const string htmlPattern = "(?<attrib>\\shref|\\ssrc|\\sbackground)\\s*?=\\s*?"
+ "(?<delim1>[\"'\\\\]{0,2})(?!#|http|ftp|mailto|javascript)"
+ "/(?<url>[^\"'>\\\\]+)(?<delim2>[\"'\\\\]{0,2})";
// 包装代码
public static string GetRelativePathReplacedHtml(string source, Uri uri)
{
source = source.HtmlAppRelativeUrlsToAbsoluteUrls( uri );
return source;
}
// 正则表达式匹配代码
public static string HtmlAppRelativeUrlsToAbsoluteUrls(this string html, Uri rootUrl)
{
if (string.IsNullOrEmpty(html))
return html;
const string htmlPattern = "(?<attrib>\\shref|\\ssrc|\\sbackground)\\s*?=\\s*?"
+ "(?<delim1>[\"'\\\\]{0,2})(?!#|http|ftp|mailto|javascript)"
+ "/(?<url>[^\"'>\\\\]+)(?<delim2>[\"'\\\\]{0,2})";
var htmlRegex = new Regex(htmlPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
html = htmlRegex.Replace(html, m => htmlRegex.Replace(m.Value, "${attrib}=${delim1}" + ("~/" + m.Groups["url"].Value).ToAbsoluteUrl(rootUrl) + "${delim2}"));
const string cssPattern = "@import\\s+?(url)*['\"(]{1,2}"
+ "(?!http)\\s*/(?<url>[^\"')]+)['\")]{1,2}";
var cssRegex = new Regex(cssPattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
html = cssRegex.Replace(html, m => cssRegex.Replace(m.Value, "@import url(" + ("~/" + m.Groups["url"].Value).ToAbsoluteUrl(rootUrl) + ")"));
return html;
}
// 网址转换
public static string ToAbsoluteUrl(this string relativeUrl, Uri rootUrl)
{
if (string.IsNullOrEmpty(relativeUrl))
return relativeUrl;
if (relativeUrl.StartsWith("/"))
relativeUrl = relativeUrl.Insert(0, "~");
if (!relativeUrl.StartsWith("~/"))
relativeUrl = relativeUrl.Insert(0, "~/");
var url = rootUrl;
var port = url.Port != 80 ? (":" + url.Port) : String.Empty;
// return string.Format("{0}://{1}{2}{3}", url.Scheme, url.Host, port, VirtualPathUtility.ToAbsolute(relativeUrl));
return string.Format("{0}://{1}{2}{3}", url.Scheme, url.Host, port, relativeUrl.Replace("~/", "/"));
}
【问题讨论】: