【问题标题】:.NET Regex: replacing links and img src.NET 正则表达式:替换链接和 img src
【发布时间】:2009-09-14 17:35:50
【问题描述】:

全部,

我需要编写一个正则表达式来执行以下操作 替换

(A)

src ="/folder/image.jpg"

src="http://www.mydomain.com/folder/image.jpg"

src="/cache/getCacheItem.aspx?source_url=http://www.mydomain.com/folder/image.jpg"

(B)

href="/folder/file.zip"

href="http://www.mydomain.com/folder/file.zip"

href="/cache/getCaccheItem.aspx?source_url=http://www.mydomain.com/folder/file.zip

我知道我可以使用

(src|href).*?=['|\"](?<url>.*?)['|\"]

替换值为

$1="/legacy_integration/cache/getCacheItem.aspx?source_url=$2"

捕捉 src=... 和 href=... 属性。但是,我需要根据文件扩展名进行过滤 - 仅匹配 jpg、png、gif 等有效图像扩展名,并且仅匹配 zip 和 pdf 等 href 扩展名。

有什么建议吗?问题可以总结为:修改上面的表达式,只匹配特定的文件扩展名,并且只有在原始url是相对的情况下才允许插入域http://www.mydomain.com/,从而保证输出文本仅包含一次域。

我是否需要使用两种不同的正则表达式来执行此操作,一种用于包含域的源文本,另一种用于不包含域的源文本?或者我可以以某种方式使用条件匹配语句,结合替换表达式,将根据匹配的文本是否包含域来插入域?

我知道我可以使用自定义匹配评估器执行此操作,但似乎在正则表达式本身内执行此操作可能更快/更有效。

建议/cmets?

【问题讨论】:

标签: .net asp.net regex


【解决方案1】:

总是出现。正则表达式不是解析非常规语法(例如 HTML)的合适工具。使用真正的解析器(如HTML agility pack)来执行此操作。

【讨论】:

  • 我不需要解析所有的 HTML,只需要解析指定的标签。我还可以控制输入数据,并且可以保证输入文本与给定格式匹配。在这里涉及另一个 3rd 方工具似乎有点矫枉过正。
  • 这不是矫枉过正,它是可靠的,如果你解析任何你都没有关系。试试吧,它会帮助解决很多问题,而不仅仅是这个。
  • 虽然我很欣赏这种完全稳定的方法,但这种特殊的解决方案是 a) 有效,b) 一种临时解决方案,允许我在新的 ASP.NET 框架中呈现大量遗留 ASP 内容,以及 c ) 在职的。正如我所说,我可以控制输入数据并且可以保证我的正则表达式有效。如果我将来需要更通用的解决方案,我会很乐意探索敏捷包。谢谢。 =)
  • 好的,我收回。 HtmlAgilityPack 很贴心。
【解决方案2】:

下面的表达式有效吗?

Regex.Replace(url, 
@"(src|href)\s*=\s*(?:'|")((?:http://www\.mydomain\.com)?.*?(jpg|bmp|png))(?:'|")",
"$1 - /cache/getCacheItem.aspx?source_url=$2");

这个想法是你有条件地匹配文本http://www.mydomain.com。它将作为 $2 匹配文本的一部分包含在内。如果它最初在那里,它将进入被替换的字符串。

【讨论】:

    【解决方案3】:

    这个呢?

    var reg = new Regex("(/folder/[^\"]+)");
    Match m = reg.Match("src=\"http://www.mydomain.com/folder/image.jpg\"");
    var result = string.Format("src=\"/cache/getCacheItem.aspx? source_url=http://www.mydomain.com{0}\"", m.Groups[1].Value);
    

    【讨论】:

    • @Espen P:看起来这会导致 URL 始终包含 mydomain.com。根据我从 OP 收集到的信息,David 希望仅当原始 URL 中存在此域时才包含该域。
    • 我可能不清楚 - 我希望包含域,无论它是否是原始 URL 的一部分。
    【解决方案4】:

    此模式将匹配任何路径,如果您想限制路径,您可以在 ?/ 之后添加它。

    (?<pre>(?:src|href)\W*=\W*(?:"|'))(?<url>(?:http://www\.mydomain\.com)?/(?<file>[^"']+))(?<post>"|')
    

    这里有一些示例代码:

    string pattern = "(?<pre>(?:src|href)\\W*=\\W*(?:\"|'))(?<url>(?:http://www\\.mydomain\\.com)?/(?<file>[^\"']+))(?<post>\"|')";
    
    string test = "src =\"/folder/image.jpg\"\r\n"
                + "src=\"http://www.mydomain.com/folder/image.jpg\"\r\n"
                + "href=\"/folder/file.zip\"\r\n"
                + "href=\"http://www.mydomain.com/folder/file.zip\"";
    
    string replacement = "${pre}/cache/getCacheItem.aspx?source_url=http://www.mydomain.com/${file}${post}";
    
    test = Regex.Replace(test, pattern, replacement);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多