Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 有条件地替换整个HTML文档中的URL(包括标题)_Regex_Vb.net_Html Agility Pack - Fatal编程技术网

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

Regex 有条件地替换整个HTML文档中的URL(包括标题),regex,vb.net,html-agility-pack,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都应排除在替换范围之外 对于找到的每

我正在寻找一种方法来更新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的其余部分。e、 g.(基于上述示例)

这将在vb.net项目中使用,在该项目中,我使用HtmlAgilityPack(HAP)执行其他替换。我不相信使用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>

图像替换
.myclass[id=mobile]{显示:块;背景图像:url(images/hero mobile.jpg)!重要;背景重复:不重复!重要;背景位置:中心!重要;}
.myclass2{背景:url(https://google.com/images/hello.jpg)不要重复!重要;}
解决方案:

这是最后一段代码,以防其他人也这么做。这是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
Dim regex作为新的正则表达式(“url\(((?:\'\))((?!(?:http | ftp))(?。+)\/(?*?)\1?\))
Dim matches As MatchCollection=regex.matches(doc.DocumentNode.InnerHtml)
将每个比赛作为比赛中的比赛
doc.DocumentNode.InnerHtml=Replace(doc.DocumentNode.InnerHtml,match.Value,“url('/MyNewDirectory/“&match.Groups(“filename”).Value&“)”)
下一个

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

url\((?:\'|\")?(.+)\/.*?\1?\)
在regex101上测试并匹配:

images
images/temp
/temp
files/folder1/temp
编辑:

抱歉,我忘了您不想包含以http开头的URL:

url\((?:\'|\")?(?!(?:http|ftp))(.+)\/.*?\1?\)
在这里,您可以添加任何要排除的前缀

如果要捕获文件名,则需要在要捕获的零件周围放上括号:

url\((?:\'|\")?(?!(?:http|ftp))(.+)\/(.*?)\1?\)
这将为您提供两个组,第一个组包含要替换的零件,第二个组包含文件名。(第一个组是非捕获组,用于标识可能的单引号或双引号,此组将不可用作捕获组,因此只有2个)

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

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

我不知道为什么长url会被截断。你能发布一个url被截断的例子吗?

这都是嵌入在CSS中的,还是仅仅是html中的纯文本?它们既出现在CSS的标题中,也出现在文档正文中的内联CSS中。为了便于讨论,可以将整个html文档解析为plaintext为了进行替换在拉取路径并剥离单引号后,您可以使用System.IO.path.GetFileName拉取文件名并将新路径附加到其中。这不只是简单的字符串替换吗?一点
RegEx
和一些if块…?谢谢,这是正确方向上的一个很好的点。我已经为您提供了将我的问题更新为包含一个示例HTML文档。您提供的正则表达式可以查找所有url()标记,但也包括以http*开头的标记,并出于某种原因截断非常长的url。我的正则表达式知识很基础,但扩展很快。我希望能够使用match.Groups(3)获得文件名.Value但只有组1包含一个值?谢谢!现在差不多了。我需要的唯一更新是正则表达式排除以http、https、//或www开头的任何url。这可能吗?是的,很抱歉忘记了这一部分。现在完成。但不确定为什么某些url被截断。需要一个示例。完美。我误解了正则表达式/误用了它,所以我需要它是截断的,但不是。非常感谢你的帮助。
url\((?:\'|\")?(?!(?:http|ftp))(?<path>.+)\/(?<filename>.*?)\1?\)