通过PowerShell提取和更新HTML字符串中的URL

时间:2014-02-14 07:18:40

标签: regex powershell

我有这个字符串(实际上有数百个)包含URL,我想更新它们。

以下是旧的网址格式
http://oldDomain/a/b/document.aspx?p1=v1&p2=NEEDED_VALUE&morePsHere=moreVsHere

以下是更新后我需要的内容
http://newDomain/c/d/NEEDED_VALUE

我需要做的就是在旧网址中提取p2的值,然后将其附加到http://newDomain/c/d/以创建新网址。

我认为我要获得的字符串看起来像这样:

$s = "http://oldDomain/a/b/document.aspx?p1=v1&p2=001&morePsHere=moreVsHere,
      http://oldDomain/a/b/document.aspx?p1=v1&p2=002&morePsHere=moreVsHere,
      http://oldDomain/a/b/document.aspx?p1=v1&p2=003&morePsHere=moreVsHere"

我可以使用以下内容进行更新:

$newURLStart = "http://newDomain/c/d/"
$newStr = $null
$s.Split(",") | ForEach {
  if ($_.IndexOf("p2=") -ne 1)
  {
    $neededValue = $_.Substring($_.IndexOf("p2=")+3)
    if ($neededValue.IndexOf("&") -ne -1)
    {
      $neededValue = $neededValue.Substring(0,$neededValue.IndexOf("&"))
    }
    $newStr = $newStr + ", " + $newURLStart + $neededValue
  }
}
$newStr = $newStr.TrimStart(", ")
$s = $newStr

但是,事实证明,我要获得的字符串不是明文,实际上看起来像是:

$s = '<div class="someClass"><p>SomeText</p><ul>
      <li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=001&amp;morePsHere=moreVsHere">LINK ONE</a></li>
      <li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=002&amp;morePsHere=moreVsHere">LINK TWO</a></li>
      <li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=003&amp;morePsHere=moreVsHere">LINK THREE</a></li>
      </ul></div>'

这比逗号分隔的期望要复杂一点!我需要帮助更新我的脚本以适应这个事实。我认为正则表达式可能会在这里抓住href中的网址,但是当谈到它时,我会非常 noob

3 个答案:

答案 0 :(得分:1)

我稍微简化了你的输入,但现在是。 (顺便说一句,请把这个正则表达式存放在你桌子旁边的一个帖子里 - 它一次又一次地帮助我!:)

我做出以下假设:

  • 输入网址仅存在于
  • 标记
  • URI始终包含参数(p1和p2)

代码:

# Heres the input. 
# I assume you can figure out how to extract the <li> tags from your input

$ip = '<li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=001&amp;morePsHere=moreVsHere">LINK ONE</a></li>
      <li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=002&amp;morePsHere=moreVsHere">LINK TWO</a></li>
      <li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=003&amp;morePsHere=moreVsHere">LINK THREE</a></li>
'

# loop through each line.
$ip -split "`n" | foreach {

        $_ -match "(?<=p2=).*(?=&amp;)"
        $matches
        # now insert the logic to put the regex match into your destination URL
} 

有关正则表达式的更多信息(和a web result):

  • -match运算符将正则表达式匹配放在名为$ matches的变量中。
  • 在上面的代码中,$ matches会在字符串的每一行中更新。
  • (?<=p2=)(?=&amp;)告诉Powershell它应该查找由表达式p2=&amp;限定的匹配项。在这种情况下,你的匹配。

继承$match

的输出
Name                           Value
----                           -----
0                              001
0                              002
0                              003
0                              003

答案 1 :(得分:1)

通过使用Powershell出色的XML功能,您可以更轻松地实现这一目标。首先,将您的字符串转换为xml:$xmlData = [xml] $s。现在,我们可以使用属性简单地导航它:$xmlData.div.ul.li.a.href将进入您获得的html,并根据需要自动扩展到集合:

PS C:\Users\carlpett> $xmlData.div.ul.li.a.href
http://oldDomain/a/b/document.aspx?p1=v1&p2=001&morePsHere=moreVsHere
http://oldDomain/a/b/document.aspx?p1=v1&p2=002&morePsHere=moreVsHere
http://oldDomain/a/b/document.aspx?p1=v1&p2=003&morePsHere=moreVsHere

现在,它只是一个简单的正则表达式来进行实际替换:$xmlData.div.ul.li.a.href -replace 'http:\/\/oldDomain\/.+p2=([^&]+).+','http://newDomain/c/d/$1'

所以,把它包起来:

$xmlData = [xml] $s
$xmlData.div.ul.li.a.href -replace 'http:\/\/oldDomain\/.+p2=([^&]+).+','http://newDomain/c/d/$1'

答案 2 :(得分:1)

如果你把所有字符串都放在一个文件中,你可以这样做:

Get-Content "testregex.html" | % {$_ -replace 'href=".+?;.+?=(.+?)&amp;(.+?)"', 'href="http://newdomain/c/$1"'} | Set-Content "newtestregex.html"

将此文件作为输入:

<div class="someClass"><p>SomeText</p><ul>
      <li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=001&amp;morePsHere=moreVsHere">LINK ONE</a></li>
      <li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=002&amp;morePsHere=moreVsHere">LINK TWO</a></li>
      <li><a href="http://oldDomain/a/b/document.aspx?p1=v1&amp;p2=003&amp;morePsHere=moreVsHere">LINK THREE</a></li>
      </ul></div>

收率:

<div class="someClass"><p>SomeText</p><ul>
      <li><a href="http://newdomain/c/001">LINK ONE</a></li>
      <li><a href="http://newdomain/c/002">LINK TWO</a></li>
      <li><a href="http://newdomain/c/003">LINK THREE</a></li>
      </ul></div>