-3

我正在尝试对某些 HTML 内容进行正则表达式替换,而我需要做的是将 URL 参数附加到已经存在的用于标记(例如锚标记、链接标记等)的 URL。例如,如果我有一个锚标签,例如

<a href="http://www.google.com">test</a> 

它应该变成(附有'?')

<a href="http://www.google.com?append=1">test</a>

但是如果已经有一个 url 参数,它应该只是附加它 - 所以,这个:

<a href="http://www.google.com?s=this&q=test">test</a> 

将变成(附加一个'&')

<a href="http://www.google.com?s=this&q=test&append=1">test</a>

我还必须考虑有时可能不一定总是有链接 - 例如

<a href="javascript:doThis('test')">test</a> 

在这种情况下,我必须不管它。

javascript中可能还嵌入了一个链接,例如:

<a href="javascript:doThis('http://www.google.com')">test</a> 
<a href="javascript:window.open('newWindow','http://www.google.com')">test</a>

这也应该像这样被替换(使用“&”或“?”):

<a href="javascript:doThis('http://www.google.com?append=1')">test</a> 
<a href="javascript:window.open('newWindow','http://www.google.com?append=1')">test</a>

(这个没那么重要——没有这个我也能活)

此外,链接可能并不总是有 http:// - 它可能只是一个相对链接:

<a href="/home.aspx?s=this&q=test">test</a> 

它应该像以前一样附加:

<a href="/home.aspx?s=this&q=test&append=1">test</a> 

我尝试了以下 - 第一个也替换了所有 javascript 链接,以及任何其他链接(不是真正的 URL)。第二个根本不工作...

    content = Regex.Replace(content, "href=\"(.*)\\?(.*)\"", "href=\"$1?append=1&$2\"", RegexOptions.IgnoreCase);
    content = Regex.Replace(content, "href=\"([^?]*)\"", "href=\"$1?append=2\"", RegexOptions.IgnoreCase);

编辑:我已经尝试过使用 HTML Agility 包,只是我得到的 HTML 格式不正确,所以它不起作用。此外,我得到的 HTML 不是一个衬里,它是我必须为此做的一整页......

4

3 回答 3

4

我建议您从使用HTML Agility Pack开始。我可能是错的,但看起来您正在使用正则表达式来确定锚标签?我会说这可能不是最好的主意,而且可能会使事情过于复杂。

您应该能够获取所有锚标记,然后从它们那里获取 href,就像文档中的这个示例一样:

例如,以下是修复 HTML 文件中所有 href 的方法:

 HtmlDocument doc = new HtmlDocument();
 doc.Load("file.htm");
 foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//a[@href"])
 {
    HtmlAttribute att = link["href"];
    att.Value = FixLink(att);
 }
 doc.Save("file.htm");

当然,这并不能完全解决您的问题,但您明白了。总的来说,我认为尝试对所有内容都使用正则表达式是一种更好的方法。

于 2012-11-30T01:02:34.390 回答
1

This is by no means robust, and I would not really suggest trying to do it this way, but if you want to try to do it with just regex and string replacing:

string source = "your html tag here";
string href = Regex.Match(source, "href=\".*\"").Value.Replace("\"", "").Replace("href=", "");
string url;
string toReplace;
bool tryToAppend = true;

if(href.Contains("'"))
{
    //if the href contains something else in quotes then its probably javascript
    //only capture something in quotes if it has a . (assume this means a url)
    url = Regex.Match(href, @"'.*\..*'").Value.Replace("'", "");

    //if we didnt find something in javascript with a . then abort
    if (url.Length == 0) 
    {
        tryToAppend = false;
    }
    toReplace = url;
}
else
{
    url = href;
    toReplace = url;
}

if (tryToAppend)
{
    if (url.Contains("?"))
    {
        url += "&append=1";
    }
    else
    {
        url += "?append=1";
    }

    source = source.Replace(toReplace, url);
}
于 2012-11-30T01:37:11.643 回答
0

这第一个正则表达式应该适用于所有双引号分隔的href。它将忽略任何以 javascript: 开头的 href。它仅涵盖您的主要场景,但很简单。

(href="(?!javascript:)[^"?]+)(?:(\?[^&"]+)(&[^"]+)?)?"

您将获得三个捕获组:

  • 第 1 组:从单词 HREF 到 URL 文件名的匹配的开头(?如果有的话,就在之前)。Example: href="http://www.google.com
  • 第 2 组: ? 和查询字符串的第一个参数。Example: ?append=1
  • 第 3 组:第一个 & 以及之后的所有内容。Example: &q=test&append=1

通过检查捕获组 2 和/或 3 是否具有值,您可以确定是否需要使用 a?或 a附加参数&。在您的示例锚点中,以下是匹配的,并且在其捕获组中具有以下值。

示例 1:  
   href="http://www.google.com
 示例 2:  
   href="http://www.google.com ?append=1
 示例 3:  
   href="http://www.google.com ?s=this &q=test
 示例 4:  
   href="http://www.google.com ?s=this &q=test&append=1
 例 10:
   href="/home.aspx ?s=this &q=test
 例 11:
   href="/home.aspx ?s=this &q=test&append=1

我尝试编写一个覆盖上述场景的正则表达式以及 javascript HREF 中路径的其他场景。它似乎有效,但这不是我所说的漂亮。为了尽可能简单,我做了以下假设:

  • HREF 值是双引号分隔的。
  • javascript 函数参数中的 URL 是绝对的,并且以 http:// 开头。

正则表达式具有与上面列出的相同的捕获组。

(href="(?:javascript:[^\(]+\([^\)]*?http://[^"?\)]+|(?!javascript:)[^"?]+))(?:(\?[^&'"]+)(&[^"']+)?)?(?:'\))?"

同样,在您的示例锚点中,以下是匹配的,并且在其捕获组中具有以下值。

示例 1:  
   href="http://www.google.com
 示例 2:  
   href="http://www.google.com ?append=1
 示例 3:  
   href="http://www.google.com ?s=this &q=test
 示例 4:  
   href="http://www.google.com ?s=this &q=test&append=1
 示例 6:  
   href="javascript:doThis('http://www.google.com
 示例 7:  
   href="javascript:window.open('newWindow','http://www.google.com
 示例 8:  
   href="javascript:doThis('http://www.google.com ?append=1
 示例 9:  
   href="javascript:window.open('newWindow','http://www.google.com ?append=1
 例 10:
   href="/home.aspx ?s=this &q=test
 例 11:
   href="/home.aspx ?s=this &q=test&append=1
于 2012-12-02T01:22:50.143 回答