Board logo

标题: [原创教程] 用 PowerShell 解析 eD2k 链接 [打印本页]

作者: victorwoo    时间: 2014-8-18 18:35     标题: 用 PowerShell 解析 eD2k 链接

本帖最后由 victorwoo 于 2014-8-18 18:38 编辑

原始链接:用 PowerShell 解析 eD2k 链接
发表日期:2014-08-18




电骡的 eD2k 链接包含了丰富的信息。例如这个:
  1. ed2k://[i]file[/i]BingPinyinSetup[i]1.5.24.02.exe[/i]31485072[i]C8C9282E6112455E624EE82941E5BA00[/i]p=79A822E1788353E0B289D2ADD5DA3BDE:FB9BB40DEDB1D2307E9D734A6416704B:0732B122C4ECF70065B181C92BF72400:437958DF590D764DE1694F91AC085225[i]h=HLXRQSANEO5MHIVOYNM5FNQOHJG3D5MP[/i]s=http://blog.vichamp.com[i]s=http://www.baidu.com[/i]/[i]sources,127.0.0.1:1234,192.168.1.1:8888[/i]/
复制代码
这给我们的第一感觉是可以用正则表达式来解析。我们观察一下它的规律,发现它是用 `|` 分割的字符串:
  1. ed2k://
  2. file
  3. BingPinyinSetup_1.5.24.02.exe
  4. 31485072
  5. C8C9282E6112455E624EE82941E5BA00
  6. p=79A822E1788353E0B289D2ADD5DA3BDE:FB9BB40DEDB1D2307E9D734A6416704B:0732B122C4ECF70065B181C92BF72400:437958DF590D764DE1694F91AC085225
  7. h=HLXRQSANEO5MHIVOYNM5FNQOHJG3D5MP
  8. s=http://www.abc.com/def.zip
  9. s=http://www.vichamp.com/qq.zip
  10. /
  11. sources,127.0.0.1:1234,192.168.1.1:8888
  12. /
复制代码
还有一些规律:

* 从 `p=` 开始,后面的段都是可选的。
* `p=xxx`、`h=xxx`、`s=xxx`看起来像键值对。
* `s=` 可以有多个,sources 后面的 IP 和端口可以有多对。

根据这个规律,我们可以很容易地构造出正则表达式,并用 PowerShell 解析它。
  1. function Get-Ed2kLink {
  2.     Param(
  3.         [string]
  4.         [Parameter(Mandatory = $true, ValueFromPipeline = $true, HelpMessage = 'Enter an ed2k:// url')]
  5.         $Link
  6.     )
  7.     $regex = [regex]@'
  8. (?x)
  9. \bed2k://
  10. \[i]file\[/i](?<FILE[i]NAME>[^[/i]]+)
  11. \[i](?<FILE[/i]SIZE>\d+)
  12. \[i](?<FILE[/i]HASH>[0-9a-fA-F]+)
  13. (?:\[i]p=(?:(?<HASH[/i]SET>[0-9a-fA-F]+):?)+)?
  14. (?:\[i]h=(?<ROOT[/i]HASH>[0-9a-zA-Z]+))?
  15. (?:\[i]s=(?<HTTP[/i]SOURCE>[^[i]]+))[/i]
  16. \|\/
  17. \[i]sources(?:,(?<SOURCES[/i]HOST>[0-9a-zA-Z.]+):(?<SOURCES[i]PORT>\d+))[/i]
  18. |\/\b
  19. '@
  20.     $match = $regex.Match($Link)
  21.     if ($match.Success) {
  22.         $sourcesHost = $match.Groups['SOURCES_HOST'].Captures | Select-Object -ExpandProperty Value
  23.         $sourcesPort = $match.Groups['SOURCES_PORT'].Captures | Select-Object -ExpandProperty Value
  24.         $sources = @()
  25.         for ($i = 0; $i -lt $sourcesHost.Length; $i++) {
  26.             $sources += [PSCustomObject][Ordered]@{
  27.                 Host = $sourcesHost[$i]
  28.                 Port = $sourcesPort[$i]
  29.             }
  30.         }
  31.         $result = [PSCustomObject][Ordered]@{
  32.             File = $match.Groups['FILE_NAME'].Value;
  33.             FileSize = $match.Groups['FILE_SIZE'].Value;
  34.             FileHash = $match.Groups['FILE_HASH'].Value;
  35.             HashSet = $match.Groups['HASH_SET'].Captures | Select-Object -ExpandProperty Value
  36.             RootHash = $match.Groups['ROOT_HASH'].Value;
  37.             HttpSource = $match.Groups['HTTP_SOURCE'].Captures | Select-Object -ExpandProperty Value
  38.             Sources = $sources;
  39.         }
  40.     } else {
  41.         $result = $null
  42.     }
  43.     return $result
  44. }
  45. Get-Ed2kLink 'ed2k://[i]file[/i]BingPinyinSetup[i]1.5.24.02.exe[/i]31485072[i]C8C9282E6112455E624EE82941E5BA00[/i]p=79A822E1788353E0B289D2ADD5DA3BDE:FB9BB40DEDB1D2307E9D734A6416704B:0732B122C4ECF70065B181C92BF72400:437958DF590D764DE1694F91AC085225[i]h=HLXRQSANEO5MHIVOYNM5FNQOHJG3D5MP[/i]s=http://www.abc.com/def.zip[i]s=http://www.vichamp.com/qq.zip[/i]/[i]sources,127.0.0.1:1234,192.168.1.1:8888[/i]/'
复制代码
执行结果如下:
  1. File       : BingPinyinSetup_1.5.24.02.exe
  2. FileSize   : 31485072
  3. FileHash   : C8C9282E6112455E624EE82941E5BA00
  4. HashSet    : {79A822E1788353E0B289D2ADD5DA3BDE, FB9BB40DEDB1D2307E9D734A6416704B, 0732B122C4ECF70065B181C92BF72400, 437958DF590D764DE1694F91AC085225}
  5. RootHash   : HLXRQSANEO5MHIVOYNM5FNQOHJG3D5MP
  6. HttpSource : {http://www.abc.com/def.zip, http://www.vichamp.com/qq.zip}
  7. Sources    : {@{Host=127.0.0.1; Port=1234}, @{Host=192.168.1.1; Port=8888}}
复制代码
注意一下,由于 `s=` 和 `sources` 节包含循环体,所以不能直接用 PowerShell 的 `-cmatch` 表达式和 `$Matches` 变量,必须用 .NET 的 `[regex]` 类来处理。

参考材料:

* eD2k 連結
* Link Creator - 用于生成 eD2k 链接。

您也可以在这里下载完整的源代码。
作者: 523066680    时间: 2014-8-18 18:43

在[i]不能发挥作用的情况下,强烈要求去掉[i] 和[/i]




欢迎光临 批处理之家 (http://bathome.net./) Powered by Discuz! 7.2