有条件地替换整个HTML文档中的URL(inc标题)

时间:2014-07-17 15:36:12

标签: regex vb.net html-agility-pack

我正在寻找一种更新HTML文档中本地文件引用的方法。

替换需要相当灵活,因为URL可能很长或很短,并且可能包含也可能不包含在引号中。主要常量是它们都将包含在url()标记中。一些例子是:

url(images/image1.jpg)
url('images/temp/image1.gif')
url('/temp/image1.png')
url(files/folder1/temp/filename.xls)

任何以http,https或www开头的网址都应从替换中排除。

对于找到的每个匹配项,我需要提取文件名并用固定的URL替换其余的URL。例如(基于上面的例子)

url(MyNewDirectory/image1.jpg)
url('MyNewDirectory/image1.gif')
url('MyNewDirectory/image1.png')
url(MyNewDirectory/filename.xls)

这将用于我正在使用HtmlAgilityPack(HAP)执行其他替换的vb.net项目中。我不相信可以使用HAP来实现上述目标,因为文件引用主要出现在HTML标题中或作为内联样式。我希望它可以通过正则表达式或一些狡猾的vb.net字符串操作。

这是一个非常基本的示例文档,显示了文件引用可能出现的一些方法。图像可以位于根目录或20个深度目录中。

<html>
  <head>
  <title>Image Replacement</title>
  <style type="text/css">
    .myclass[id=mobile] { display:block;  background-image: url(images/hero-mobile.jpg) !important; background-repeat: no-repeat !important; background-position: center !important;}
    .myclass2 { background:url(https://google.com/images/hello.jpg) no-repeat !important; } 
  </style>
  </head>
  <body topmargin="0" bottommargin="0" leftmargin="0" rightmargin="0" bgcolor="#f8f7f5" style="background-color:#f8f7f5; background-image: url('/images/directory1/directory2/anotherimage.jpg') ">
    <table cellpadding="0" cellspacing="0" align="center" width="100%" border="0" bgcolor="#f8f7f5" style="background-color:#f8f7f5; background-image: url(thisimage.jpg)">
      <tr>
        <td>
        </td>
      </tr>
    </table>
  </body>
</html>

解决方案:

这是最终的代码,以防其他人试图做同样的事情。这是vb.net,HAP在doc.DocumentNode.InnerHtml中提供整个HTML内容:

Dim regex As New Regex("url\((?:\'|\"")?(?!(?:http|ftp))(?<path>.+)\/(?<filename>.*?)\1?\)")
Dim matches As MatchCollection = regex.Matches(doc.DocumentNode.InnerHtml)
For Each match As Match In matches
  doc.DocumentNode.InnerHtml = Replace(doc.DocumentNode.InnerHtml, match.Value, "url('/MyNewDirectory/" &  match.Groups("filename").Value & "')")
Next

1 个答案:

答案 0 :(得分:0)

此正则表达式将捕获您要在一个捕获组中替换的URL部分。 仅使用您提供的4个示例进行测试:

url\((?:\'|\")?(.+)\/.*?\1?\)

在regex101上测试并匹配:

images
images/temp
/temp
files/folder1/temp

修改

抱歉,我忘了您不想包含以http:

开头的网址
url\((?:\'|\")?(?!(?:http|ftp))(.+)\/.*?\1?\)

您可以在此处添加要排除的任何前缀。

如果您想要捕获所有文件名,只需在要捕获的部分周围放置括号:

url\((?:\'|\")?(?!(?:http|ftp))(.+)\/(.*?)\1?\)

这将为您提供2组,第一组包含您要替换的部分,第二组包含文件名。 (第一组是非捕获组,用于识别可能的单引号或双引号,这一组将不会作为捕获组提供,因此只会有2个)

您还可以使用命名组来使其更清晰:

url\((?:\'|\")?(?!(?:http|ftp))(?<path>.+)\/(?<filename>.*?)\1?\)

我不确定为什么长网址会被截断。你能发贴一个被截断的网址示例吗?