如何在Powershell正则表达式

时间:2015-10-17 01:55:47

标签: regex powershell powershell-v2.0

我遇到了一个脚本,我正在整理下载最新的安装包而不需要使用Chocolatey或Ketarin。遗憾的是,直接下载链接未提供一些实用程序,并且隐藏在重定向URL后面,下载URL在15分钟后到期。为了使事情进一步复杂化,我在PowerShell 2中这样做,因为我们办公室里有一些Vista机器。

在研究了其他类似的场景之后,似乎我可以调用.NET WebClient来处理下载,尽管没有进度条。由于我没有找到一段代码来处理在.NET WebClient工作一段时间后重定向后面的文件,我决定我可以做的是使用WebClient请求加载页面,然后获取使用以下正则表达式从页面当前直接下载URL,然后使用正则表达式来下载该文件。我已经检查过regexr.com以验证正则表达式是否捕获了下面的示例网址。

示例网址

<a href="https://www.example.com/randomstring003ejdjd38/dl/ProgramName.exe">CF DL here</a>

正则表达式

<a(?: [^>]*?)? href=(["'])([^\1]*?ProgramName*?)\1(?: .*?)?>.*?<\/a>

不幸的是,Powershell会对此进行红色标记,因为它似乎认为双引号需要终止。在尝试使用反引号来逃避任何带有红色标记的字符后,我结束了以下操作,这会引发一个错误,指出'?:'不被识别为术语,cmdlet等。

$downloadLinkRegex = New-Object System.Text.RegularExpressions.Regex (<a(?: [^>]*?)? href=(`[`"`'])(`[`^\1]*?ProgramName.exe*?)\1(?: .*?)?>.*?</a>)
if ("https://www.example.com/randomstring003ejdjd38/dl/ProgramName.exe" -match $downloadLinkRegex){
write-host "yay"
} else{
write-host "nope"}

企图逃脱?使用反引号也失败了。正则表达式对我来说是非常困难的,所以在这一点上我没有关于如何使ISE认识到这是一个有效的正则表达式的想法,并且它不需要被验证,并且它可以存储为稍后将在webrequest的内容上调用的变量的值。

如果有人能够指出我出错的地方,或者如何解决问题,我将非常感激。

5 个答案:

答案 0 :(得分:1)

我能想到的最简单的方法是在powershell中使用@“bla”@ block(我不知道正式名称)。 例如 : $ regex = @“ 在这里插入正则表达式 “@  @“”@ block之间的所有内容都将被视为字符串值。

答案 1 :(得分:1)

我刚删除了PowerShell标记项。我必须测试几种不同的方法来确保这是PowerShell让我打印到HTML的唯一方法。即使ConvertTo-HTML也不会绕过PowerShell的问题。它就像HTML的混合体。我还注意到,当你键入时,PowerShell不会注意空格,所以我的真实代码有很多空格和空行来区分我的脚本。

$My_HTML_table = "<!DOCTYPE html>
<head><title> My Excellent Page </title></head>
<H2> Table 1 </H2>
<text></text>
<table border=1;border-style:solid>
<tr>
<td colspan=1 style=color:blue;background-color:#CCCCCC;font-size:18;padding:5px> Cute Header </td>
</tr>"
$My_HTML_table > C:\File_Path\My_Excellent_HTML.html

答案 2 :(得分:0)

但它在regexr.com上不匹配......?它失败了,因为它认为</a>是正则表达式的结束。它也失败了,因为它试图匹配ProgramNam(一个或无限'e')并忽略.exe位。 (并且“一定不能匹配八进制数字”?这可能不是你想要的那些(不,我不知道,我只是在试图在regex101.com上破译时我只是看到了它))。

无论如何,对于你的问题:PowerShell没有正则表达式文字,因此你不能只将<a(?: [^>]*?...写入shell并让它工作。它们必须是字符串。

但它们不必经过New-Object System.Text.RegularExpressions.Regex

e.g。

$url = '<a href="https://www.example.com/randomstring003ejdjd38/dl/ProgramName.exe">CF DL here</a>'

$pattern = "<a.*?href=[`"'](.*?)[`"'][^>]*>.*?</a>"

$url -match $pattern
$Matches[1]

我在外面用双引号引用了字符串。然后我用一个反引号来逃避模式中的双引号。

正则表达式模式为explained much more helpfully here

答案 3 :(得分:0)

我实际上将正则表达式重写为更简单的解决问题的方法。虽然URL不断更改文件名,但我专注于文件名,而不是整个URL,并且能够获取我需要的URL。

答案 4 :(得分:0)

看起来不错

$a='<a href="https://www.example.com/randomstring003ejdjd38/dl/ProgramName.exe">CF DL here</a>'
$a -match '(?<=ef=")[^"]+?(\w+).(exe|pdf)'
Iwr $matches[0] -outfile "$($matches[1]).$($matches[2])"